6

好的,前面的问题已经回答得很清楚了,但我发现了另一个问题。

如果我这样做怎么办:

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 转换为字符串?

4

5 回答 5

9

在这里,您不是将 转换char*a [std::]string,而是将 复制char*a [std::]string

根据经验,每个都new应该有一个delete.

在这种情况下,您需要在完成后存储指针及其副本delete

char* temp = test(rand()%10000000+10000000);
string str = temp;
delete[] temp;
于 2010-06-03T13:44:35.503 回答
3

您似乎认为将 a 传递给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; 
} 
于 2010-06-03T13:53:22.627 回答
2

是的,是的,你知道。

如果您使用的是 linux/os x,请查看valgrind 之类的东西,它可以帮助您解决内存问题

您可以更改测试函数,使其返回 astring而不是char *,这样您就可以delete [] ret在测试函数中。

或者您也可以在测试中使用字符串,而不必担心新/删除。

于 2010-06-03T13:43:38.683 回答
2

必须调用delete每一个,new否则你会泄漏内存。在您已经表明要丢弃指针的情况下,如果您必须将函数保留为返回 a ,char*那么您将需要使用两行来创建 the ,std::string以便保留char*to的副本delete

更好的解决方案是重写您的test()函数以直接返回 a std::string

于 2010-06-03T13:58:13.507 回答
2

你需要做这样的事情:

for(int i = 0; i < 100000000; i++){ 
   int length = rand()%10000000+10000000;
   char* tmp = test(length); 
   string str(tmp);
   delete[length] tmp;
}

这会正确删除分配的字符数组。

顺便说一句,如果您以这种方式创建字符串(即在函数内部test),您应该始终以零结尾,否则某些函数很容易“混淆”并将字符串后面的数据视为它的一部分,这在最好的情况下使您的应用程序崩溃,并在最坏的情况下创建静默缓冲区溢出,导致稍后出现未定义的行为,这是最终的调试噩梦......;)

于 2010-06-04T00:20:38.943 回答