【问题标题】:How to free memory of N elements of an array如何释放数组的 N 个元素的内存
【发布时间】:2023-04-06 18:56:01
【问题描述】:

与我正在修复的 the program from 2004 相关。前开发人员使用以下代码在析构函数中释放数组的 'len' 元素:

unsigned int* _data;  
...  
if (_data) {
  int len = size();
  delete (unsigned int[len]) _data;
}

我无法用我的编译器编译此代码。错误信息是:

错误:ISO C++ 禁止转换为数组类型‘unsigned int [(((unsigned int)(((int)l) + -0x00000000000000001)) + 1)]’

他不使用@987654323一定是有原因@我应该如何解决这个错误?
谢谢。

【问题讨论】:

  • 那个代码当时毫无意义,现在也毫无意义。您的编译器更擅长捕捉这种暴行。只需delete[] _data
  • 首先不使用手动动态分配;使用std::vector<unsigned int>。如果您想手动清除它,请执行以下操作:clear()
  • 原因可能是无知。其余代码是否让您认为他知道自己在做什么?
  • 鉴于上面的cmets,当提到代码来自2004年编写的应用程序并且没有人接触时,不要试图建议不要使用数组,使用向量等到现在为止。在大多数公司中,进行不在范围内的更改是不可接受的。如果你的情况不是这样,那么我猜你正在做一些对业务而言不是那么重要的事情。
  • @Jagannath:如果您的公司阻止您进行这些更改,您可以忽略这些建议。对于其他阅读该问题的人,该建议很有用。

标签: c++


【解决方案1】:

我应该如何解决这个错误?

移除演员表,寻找_data被分配的地方。

  • 如果已分配为new [someLength],则替换为delete[] _data;
  • 否则(尽管不太可能)替换为 delete _data

从长远来看,最好使用动态容器,例如std::vector<unsigned int>,而不是动态分配基元数组。不过,我知道这可能超出了您当前重构的范围。

【讨论】:

  • 虽然在这种情况下,因为 _data 只是一个指向 int 的指针,所以执行 delete[] 与 delete 没有什么不同,因为没有要调用的析构函数。
  • @koodawg:在正确的意义上它是不同的,并且不会调用未定义的行为。非常重要的区别,imo。
【解决方案2】:

首先,检查您是否在代码中的某处动态分配_data。如果没有new 表达式,则不能使用delete

如果它是使用new动态分配的,当你需要释放那个对象时,你应该问自己:“这个指针是指向单个对象,还是指向一个对象数组?”。这一点非常重要,因为每种情况下的内存布局都不同,delete 必须提前知道它应该调用多少个析构函数。如果它调用了错误数量的析构函数,则会发生未定义的行为。

经验法则是使用delete [] 当且仅当您在new 表达式中使用[] 分配了该对象。

【讨论】:

  • “每种情况下的内存布局都不一样”——是吗?
  • 内存布局是实现定义的。它可以分配一个巨大的块并将它们全部塞在一起,它可以在元素之间留出空间(类似于结构打包),它可以单独分配每个数组元素。谁知道?然而,在实践中,它通常会略有不同。
  • @OliCharlesworth 这取决于实现,但通常是这样。
  • @DanielMartín:我很欣赏标准允许这样做(因此我完全同意deletedelete[] 很重要),但我的印象是new 和@在大多数实现中,987654331@ 基本上都会在后台调用malloc
  • 从理论上讲,它可能会在元素之间留下空隙。例如,也许一个字节数组的每个元素都在字边界上对齐(例如 4/8 字节)以提高访问效率。在实践中,这种情况很少发生。我的观点是标准将其留给实施。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多