【问题标题】:mismatch new[] and delete, why is there no memory leak? [duplicate]不匹配new[]和delete,为什么没有内存泄漏? [复制]
【发布时间】:2017-04-28 06:52:54
【问题描述】:

当将new[]delete 组合而不是delete[] 时,究竟会发生什么?试了下面的代码,发现没有内存泄漏,那为什么delete上的new[]返回的指针不会导致内存泄漏呢?

编译器如何知道要释放的字节数?

int main() {
  constexpr int size = 102400;
  while (1) {
    char* buffer = new char[size]{};
    delete buffer;
  }

  return 0;
}

【问题讨论】:

  • 我这里不是说valgrind,我想知道如果你删除了一个new[]指针,它怎么算出要释放的块大小?
  • 现在你有一个很好的问题。但更进一步:它如何确定您分配的数组是一个元素还是一百万个元素?
  • 没有[],代码不需要工作,但也不需要工作。

标签: c++ memory-leaks delete-operator


【解决方案1】:

程序行为正式未定义,因为您需要将new[]delete[] 匹配。

但未定义行为的一种可能表现是编译器“玩得很好”,并按照您的意愿行事。 (我使用的其中一个编译器会执行此操作,并构成其文档的一部分。)

但是不要依赖,否则你写的不是严格可移植的 C++。

还请注意,您可能不会观察内存泄漏,因为 C++ 运行时库和操作系统在您使用它之前可能不会真正为您提供内存。编译器甚至可以完全优化您的循环 - 因为它是无操作的 - 特别是在正确编写内存分配和释放调用的情况下。

【讨论】:

  • 这里说到gcc,如果调用delete而不是delete[],它怎么知道实际要释放的大小?
  • @bugsking 实际字节大小可能存储在分配内存前面的标头中。但这仍然是未定义的行为。如果创建具有析构函数的类类型的数组,则可能会发生泄漏。 delete 不会调用所有数组元素的析构函数,而delete[] 会。
【解决方案2】:

如果启用了优化,那么编译器可以删除您的 while 循环或内部内存分配和释放。否则如前所述,您的程序具有未定义的行为。

【讨论】:

  • O0编译,没有优化。
猜你喜欢
  • 1970-01-01
  • 2011-03-05
  • 2010-11-19
  • 2012-04-12
  • 2015-11-06
  • 2012-12-07
  • 2011-02-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多