【问题标题】:C++ new & delete and string & functionsC++ 新 & 删除和字符串 & 函数
【发布时间】:2010-06-03 13:41:45
【问题描述】:

好的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正确串起来?

【问题讨论】:

  • 回复:编辑...不要丢失指针(根据我下面的回答)或(更好)不要 new 指针,只需使用 std::string 保持细绳。为什么要自己做内存分配?

标签: c++ string char new-operator delete-operator


【解决方案1】:

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

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

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

char* temp = test(rand()%10000000+10000000);
string str = temp;
delete[] temp;

【讨论】:

  • 那么如何正确地将 char 转换为字符串?
  • 我猜当您被告知将char* 转换为std::string 时,您应该使用 std::string 而不是char*,而不是以编程方式转换。
  • 有没有更简单的方法可以做到这一点?比如某种函数什么的,所以只需要一行代码?
  • 最简单的方法是在存储string 时避免使用char*。您可以使用智能指针,但这是我现在不准备打开的全新蠕虫罐头。
  • 是的,您可以执行return string( ran, 'a' ) 之类的操作。看看字符串构造函数cplusplus.com/reference/string/string/string
【解决方案2】:

您似乎认为将 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; 
} 

【讨论】:

  • +1 用于跳过创建 char * 的中间步骤。也就是说,您的示例代码缺少名称...
【解决方案3】:

是的,是的。

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

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

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

【讨论】:

  • 所以我必须使用:delete[] str; ?
  • 不,str 是它自己的对象。在这种情况下,您丢失了指向您分配的新 char[] 的指针,因此由于您无法删除它,因此会发生内存泄漏。
【解决方案4】:

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

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

【讨论】:

    【解决方案5】:

    你需要做这样的事情:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-30
      • 2013-04-12
      • 2016-07-04
      • 1970-01-01
      • 2018-03-23
      • 2019-05-29
      • 2016-09-30
      • 2015-02-02
      相关资源
      最近更新 更多