如何在 C++ 中动态 allocated/grow 一个字符串数组?
How do I dynamically allocated/grow an array of strings in C++?
环顾四周,我找到了我认为可以解决我的问题的方法。现在我正在尝试读取一个 txt 文件。
来自文件的片段:
11111,"random phrase"
11123,"this is nonsense"
13212,"silly words"
int arraylen = 2;
string line, field;
string* num = new string[arraylen];
string* phrase = new string[arraylen];
ifstream myfile;
myfile.open("data.txt");
int i = 0, test = 0;
while(!myfile.eof())
{
getline(myfile,line);
stringstream ss(line);
while(getline(ss,field,','))
{
if(test == 0)
{
num[i] = field;
cout << "rum: " << num[i] << endl;
test = 1;
}
else
{
phrase[i] = field;
cout << "phrase: " << phrase[i] << endl;
test = 0;
}
if(i == (arraylen-1))
{
arraylen = arraylen + 1;
string* temp = new string[arraylen];
copy(num, num + 2, temp);
delete [] num;
num = temp;
copy(phrase, phrase + 2, temp);
delete [] phrase;
phrase = temp;
}
}
i++;
}
myfile.close();
return 0;
我解析逗号处的行并将数字保存到数组 num,将短语保存到数组 phrase。我想让我的程序读入一个行数未知的文件,所以我需要动态地增加数组。现在,如果我使用被注释掉的数组,我的程序就会崩溃。
couts 显示它正在读取前两行然后崩溃我假设是因为数组不够长。关于需要进行哪些更改以便我可以适当地增加阵列的任何建议?
编辑:我必须使用数组。我不能使用任何其他数据结构。
分配一个新数组。将旧数组复制到新数组。删除旧数组。
void reallocate(std::string** old_arr, int old_size, int new_size)
{
std::string* new_arr = new std::string[new_size];
for (int i = 0; i < old_size; ++i)
new_arr[i] = (*old_arr)[i];
delete[] *old_arr;
*old_arr = new_arr;
}
这只是因为您不能使用评论中指定的 std::vector
。下一个选项是使用 std::unique_ptr
但是 meh.. 这个想法很简单,当你分配新数组时,将 new_size 指定为 old_size * 2.. 这通常是什么 std::vector
确实如此。
请注意,此处的代码不是异常安全的,并且会忽略 C++11 移动语义。
只需使用 std::vector
.
例如您可以使用 push_back
方法将项目添加到 std::vector
的末尾,使其增长。
std::vector
也比直接处理原始指针和 new
.
更安全、更容易
如果您的讲师禁止使用 std::string
以外的标准库容器,则使用 std::vector
的一些相关功能实施 class。这样的class重要的是负责复制,在C++03时代被称为“3规则”。本质上,由于它将处理动态内存分配和释放,您将需要一个析构函数,因此您需要声明(并实现或设置为 delete
)一个复制构造函数和一个复制赋值运算符。
在这个class中,当超过当前缓冲区大小时,分配一个新的缓冲区,将旧的内容复制过来,释放旧的。避免 O(n2) 行为的一种常见方法是将缓冲区大小增加一些 因素,而不仅仅是固定数量的项目.每次将缓冲区大小简单地加倍可能就足够了。
哦,是的,在内部使用智能指针是个好主意。
环顾四周,我找到了我认为可以解决我的问题的方法。现在我正在尝试读取一个 txt 文件。
来自文件的片段:
11111,"random phrase"
11123,"this is nonsense"
13212,"silly words"
int arraylen = 2;
string line, field;
string* num = new string[arraylen];
string* phrase = new string[arraylen];
ifstream myfile;
myfile.open("data.txt");
int i = 0, test = 0;
while(!myfile.eof())
{
getline(myfile,line);
stringstream ss(line);
while(getline(ss,field,','))
{
if(test == 0)
{
num[i] = field;
cout << "rum: " << num[i] << endl;
test = 1;
}
else
{
phrase[i] = field;
cout << "phrase: " << phrase[i] << endl;
test = 0;
}
if(i == (arraylen-1))
{
arraylen = arraylen + 1;
string* temp = new string[arraylen];
copy(num, num + 2, temp);
delete [] num;
num = temp;
copy(phrase, phrase + 2, temp);
delete [] phrase;
phrase = temp;
}
}
i++;
}
myfile.close();
return 0;
我解析逗号处的行并将数字保存到数组 num,将短语保存到数组 phrase。我想让我的程序读入一个行数未知的文件,所以我需要动态地增加数组。现在,如果我使用被注释掉的数组,我的程序就会崩溃。
couts 显示它正在读取前两行然后崩溃我假设是因为数组不够长。关于需要进行哪些更改以便我可以适当地增加阵列的任何建议?
编辑:我必须使用数组。我不能使用任何其他数据结构。
分配一个新数组。将旧数组复制到新数组。删除旧数组。
void reallocate(std::string** old_arr, int old_size, int new_size)
{
std::string* new_arr = new std::string[new_size];
for (int i = 0; i < old_size; ++i)
new_arr[i] = (*old_arr)[i];
delete[] *old_arr;
*old_arr = new_arr;
}
这只是因为您不能使用评论中指定的 std::vector
。下一个选项是使用 std::unique_ptr
但是 meh.. 这个想法很简单,当你分配新数组时,将 new_size 指定为 old_size * 2.. 这通常是什么 std::vector
确实如此。
请注意,此处的代码不是异常安全的,并且会忽略 C++11 移动语义。
只需使用 std::vector
.
例如您可以使用 push_back
方法将项目添加到 std::vector
的末尾,使其增长。
std::vector
也比直接处理原始指针和 new
.
如果您的讲师禁止使用 std::string
以外的标准库容器,则使用 std::vector
的一些相关功能实施 class。这样的class重要的是负责复制,在C++03时代被称为“3规则”。本质上,由于它将处理动态内存分配和释放,您将需要一个析构函数,因此您需要声明(并实现或设置为 delete
)一个复制构造函数和一个复制赋值运算符。
在这个class中,当超过当前缓冲区大小时,分配一个新的缓冲区,将旧的内容复制过来,释放旧的。避免 O(n2) 行为的一种常见方法是将缓冲区大小增加一些 因素,而不仅仅是固定数量的项目.每次将缓冲区大小简单地加倍可能就足够了。
哦,是的,在内部使用智能指针是个好主意。