好的previous问题得到了清楚回答,但我发现了另一个问题。
如果我这样做:
char *test(int ran){
char *ret = new char[ran];
// process...
return ret;
}
然后运行它:
for(int i = 0; i < 100000000; i++){
string str = test(rand()%10000000+10000000);
// process...
// no need to delete str anymore? string destructor does it for me here?
}
所以在将char *转换为字符串之后,我不必再担心删除了吗?
编辑:如上所述,我必须delete[]
每次new[]
调用,但就我的情况而言,由于指针丢失,因此无法实现,所以问题是:如何我正确地将char转换为字符串吗?
答案 0 :(得分:9)
此处您 将char*
转换为<{1}},但将<{em} [std::]string
转换为char*
}。
根据经验,对于每个[std::]string
,应该有一个new
。
在这种情况下,您需要在完成后存储指针的副本并delete
:
delete
答案 1 :(得分:3)
您似乎受到了恳求,即将char*
传递给std :: string会转移已分配内存的所有权。事实上,它只是制作副本。
解决此问题的最简单方法是在整个函数中使用std :: string并直接返回。
std::string test(int ran){
std::string ret;
ret.resize(ran - 1); // If accessing by individual character, or not if using the entire string at once.
// process... (omit adding the null terminator)
return ret;
}
答案 2 :(得分:2)
是的,是的。
如果您使用的是linux / os x,请查看类似valgrind的内容,它可以帮助您解决内存问题
您可以更改测试功能,使其返回string
而不是char *
,这样您就可以在测试函数中delete [] ret
。
或者您也可以在测试中使用字符串,而不必担心新的/删除。
答案 3 :(得分:2)
必须为每delete
调用new
否则会泄漏内存。如果您已经显示丢弃指针,如果您必须将函数保留为返回char*
,那么您将需要使用两行来创建std::string
,这样您就可以保留副本char*
到delete
。
更好的解决方案是重写test()
函数以直接返回std::string
。
答案 4 :(得分:2)
你需要做这样的事情:
for(int i = 0; i < 100000000; i++){
int length = rand()%10000000+10000000;
char* tmp = test(length);
string str(tmp);
delete[length] tmp;
}
这会正确删除已分配的char数组。
顺便说一下,如果以这种方式创建字符串(即在函数test
内),你应该始终将字符串置零,否则某些函数很容易“混淆”并将字符串后面的数据作为一部分处理它,在最好的情况下崩溃您的应用程序,并在最坏的情况下创建一个静默缓冲区溢出导致以后的未定义行为,这是最终的调试噩梦...;)