【问题标题】:Deleting a non-owned dynamic array through a pointer通过指针删除非拥有的动态数组
【发布时间】:2010-04-12 04:00:40
【问题描述】:

我在 C++ 方面相对新手,因为我在本科课程的大部分时间里都在学习 Java(很遗憾)。内存管理一直很麻烦,但我已经购买了有关 ansi C 和 C++ 的数字书籍。我已经浏览了相关问题,但找不到符合此特定标准的问题。可能这么明显没人提?

这个问题一直困扰着我,但我觉得好像有一个我没有利用的概念点。

假设:

char original[56];
cstr[0] = 'a';
cstr[1] = 'b';
cstr[2] = 'c';
cstr[3] = 'd';
cstr[4] = 'e';
cstr[5] = '\0';
char *shaved = shavecstr(cstr); 
// various operations, calls //
delete[] shaved;

在哪里,

char* shavecstr(char* cstr) 
{
    size_t len = strlen(cstr);
    char* ncstr = new char[len];
    strcpy(ncstr,cstr);
    return ncstr;
}

其中的重点是让“原始”成为一个填充字符的缓冲区,并定期将其副本剃掉并在其他地方使用。

为了澄清,原件是通过std::gets(char* buff)std::getline(char* buff, buff_sz)std::read(char* buff, buff_sz) 或任何就地填充输入阅读器填充的。为了“刮”一个字符串,它基本上被截断以消除未使用的数组空间。

该错误是堆分配错误,并在delete[] 上分段。

为了防止泄漏,我想释放 'shaved' 持有的内存,以便在它通过一些参数后再次使用。这可能有一个很好的理由来限制它,但是应该有一些方法可以释放内存,因为通过这种配置,没有办法访问数据的原始所有者(指针)。

【问题讨论】:

  • 您的original 缓冲区在哪里使用? cstr 应该是 original 吗?
  • 您遇到了什么问题?有编译器错误吗?除了变量名称错误之外,我不理解您要通过“剃须”完成什么,究竟是什么问题?如果你认真使用 C++,你应该使用 std::string 而不是 char*,并且完全避免整个内存管理混乱。
  • 而且 cstrn 应该是 cstr 吗?
  • 哦,是的,您忘记为空终止符分配空间,所以strcpy 正在注销您的数组末尾。如果你必须使用 C 风格的字符串,首选strncpy
  • 不要责怪编译器。您的代码失败是有原因的。很可能是由于超出数组末尾而导致的内存损坏。

标签: c++ pointers memory-management dynamic-data delete-operator


【解决方案1】:

我假设您将original 替换为cstr,否则代码将无法编译,因为cstr 未声明。

这里的错误是分配的数组的大小太小了。您希望 char* ncstr = new char[len+1]; 负责终止 \0

另外,如果你在函数返回后立即删除shaved,那么调用函数就没有意义了……

[*] 更深入一点,用于cstr 的内存将在包含函数返回时被释放。通常,此类静态字符串被放置在在应用程序的整个期间都存在的常量中。例如,您可以在所有函数之外拥有const char* cstr="abcde";。然后你可以传递这个字符串而不必动态分配它。

【讨论】:

    【解决方案2】:

    假设您打算使用 cstr 而不是 cstrn...

    您不应该删除cstr。你应该删除shaved

    您只有delete 分配给new 的内存。还有delete[] 分配给new[] 的内存。

    shaved 只是一个保存内存地址的变量。您将该内存地址传递给delete[] 以摆脱内存。 shaved 保存用new[] 分配的内存的内存地址。

    【讨论】:

      猜你喜欢
      • 2018-03-30
      • 1970-01-01
      • 2022-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-09
      • 1970-01-01
      相关资源
      最近更新 更多