我需要一个动态的字符串数组,以便我可以随时扩展它。所以我想用malloc / realloc来做。但是每当我尝试运行它时,我会从valgrind发现以下错误导致分段错误:
==13709== Use of uninitialised value of size 8
==13709== at 0x4EEED9B: std::string::assign(char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
==13709== by 0x400953: main (test.cpp:12)
==13709==
==13709== Invalid read of size 8
==13709== at 0x4EEED9B: std::string::assign(char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
==13709== by 0x400953: main (test.cpp:12)
我的代码看起来像这样:
int main()
{
string* arr;
arr=(string*) malloc(5*sizeof(string));
arr[0]="test1";
arr[1]="test2";
cout << arr[0] << arr[1] << endl;
}
我知道char **,但使用时有点痛苦,所以我想使用字符串。有关如何使其有效的任何提示吗?
答案 0 :(得分:6)
总结评论:
malloc(5*sizeof(string))
只会分配足够大的内存以容纳5 std::string
s。类型对象(如std::string
)需要在分配内存后初始化,这意味着在使用对象之前构造对象。尝试使用未初始化的内存,就好像它是一个有效的初始化std::string
对象一样,会给你未定义的行为。
在C ++中,使用new
运算符执行动态内存分配。也就是说,您的行将被写为arr = new string[5];
。这为5 std::string
s分配空间,并构建所有这些空间。然后他们就可以使用了。
但是,在C ++中,我们尝试避免自己执行动态内存分配,因为它会导致错误和不安全的代码。相反,我们使用封装此行为的类(通常由标准库提供的类)。在这种情况下,您最好使用std::vector<std::string>
代表std::string
的容器,可以轻松添加,删除,调整大小等,而不会有手动动态分配的危险
为了证明这是多好,这是我编写代码的方式:
int main() {
std::vector<std::string> arr = {"test1", "test2"};
std::cout << arr[0] << arr[1] << std::endl;
}
答案 1 :(得分:1)
我需要一个动态的字符串数组,以便我可以扩展它 随时。所以我想用malloc / realloc来做 [...]
有关如何使其有效的任何提示吗?
只需使用 std::vector<std::string>
。
通过这种方式,所有内存管理都在“引擎盖下”自动发生 它将使您的代码更容易进行阅读和维护。
在现代C ++中(除非有充分的理由不这样做),考虑使用方便的 STL容器类,如std::vector
和字符串类,如std::string
,而不是原始 C类指针。
如果您想为向量添加更多字符串,只需调用std::vector
的 push_back()
方法,即可为新字符串创建新房间,并且矢量更新正确。
vector
和string
的析构函数将自动为您释放内存。
这是对原始malloc
/ free
(或new[]
/ delete[]
)的重大胜利。