【问题标题】:Deleting a dynamic array after it has been returned from a function从函数返回后删除动态数组
【发布时间】:2016-02-18 05:55:43
【问题描述】:

我是 C++ 新手,对内存泄漏有偏执。我将把我的代码精简到最重要的部分:

如果我有这样的功能:

char * myString = "Discombobulate";

char * ToUppercase()
{
    int length = strlen(myString);
    char * duplicateString = new char [length];
    strcpy(duplicateString, myString);
    //char arithmetic to turn every letter in duplicateString to uppercase
    return duplicateString;
}

显然,我需要执行 delete[] 以避免内存泄漏。现在我想知道我是否可以在 main() 中进行删除,如下所示:

int main () {
char * result = Upper();

std::cout << result << std::endl;

delete[] result;
}

这会正常工作吗?这样做有什么问题吗?

【问题讨论】:

  • 为什么在 C++ 中使用char* 而不是std::string?此外,您的函数名称不匹配。
  • 使用 RAII 成语。返回具有将管理此类资源的值语义的类。在这种情况下,只需返回 std::string
  • strcpy(duplicateString, myString); 是未定义的行为,duplicateString 是一个字符太短(空字符没有空间),以防万一您需要另一个使用 std::string 的理由。
  • 糟糕的例子我知道,我在大约 2 秒内输入了它。
  • 如果您对内存泄漏有疑虑,您应该坚持使用当代 C++。在资源周围使用 RAII 包装器,例如std::vector 而不是 C 风格的数组。如果您从一本书中学习,并且它在 C 数组之后引入了 std::vector 或在 C 字符串处理之后引入了 std::string,我会把它扔掉。

标签: c++ memory dynamic


【解决方案1】:

现在我想知道是否可以在 main() 中进行删除

是的,你可以而且你应该这样做。

BTW1:考虑使用std::stringstd::vectorsmart pointers,以避免这种手动内存管理,因为它是 c++。

顺便说一句:

char * duplicateString = new char [length];

应该是

char * duplicateString = new char [length + 1];

最后一个位置将用于终止空字符'\0'

【讨论】:

  • 是的,我输入的例子相当粗心。
【解决方案2】:

这会正常工作吗?

是的。只要它是一个有效的指针,你就可以在调用new 的函数之外delete 它。你应该?嗯……

这样做有什么问题吗?

是的。这是不好的做法。您在函数中分配资源并期望调用者清理它们。正如 cmets 中的人所解释的那样,它与 RAII 相违背。除了使用std::string(一定要使用它)的建议外,您还可以使用std::unique_ptr 和朋友来代替原始指针。

【讨论】:

    【解决方案3】:

    是的,您可以按照自己的方式删除它...顺便说一句,您还可以为指针分配内存并将其作为参数传递给函数,并在函数返回后将其删除。

    char * duplicateString = new char [length + 1];
    
    ToUppercase(char* duplicateString );
    
    if( duplicateString ){ delete []duplicateString  ; duplicateString  = NULL;}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-28
      • 2021-09-27
      • 2021-01-15
      • 2017-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多