c++ - 为什么我不能通过指针从数组中删除非第一个元素

标签 c++ arrays memory-management memory-leaks heap-memory

考虑以下代码:

int main()
{
  int *intArPtr = new int[100];
  int *intArPtr1 = intArPtr + 1;

  delete [] intArPtr; //ok
  //delete intArPtr; //valgrind warning, but no leaks!
  //delete intArPtr1; //invalid pointer error

  return 0;
}

我知道 delete [] intArPtr 是删除此数组的唯一有效方法,但我只是对以下内容感到好奇:

  1. 为什么 delete intArPtr 不会产生任何内存泄漏?是吗 未定义的行为,我很幸运没有任何行为?
  2. 为什么 delete intArPtr1 会在运行时出错?为什么它不删除所有元素,而是首先从数组中删除?
  3. C++ 的运行时如何知道分配数组的大小(对于 delete [])?它存储在某个地方吗?

最佳答案

  1. Why delete intArPtr doesn't yield any memory leaks? Is it undefined behavior and I'm just lucky no to have any?

正确,在用 new[] 分配的内存上调用 delete 是未定义的行为。其一,它不会调用数组成员的析构函数。

对于两个,即使您只是询问内存释放而不是对象销毁,deletedelete[] 也有可能以相同的方式实现,或者他们是不同的。它们读起来好像它们是相同的东西,但它们不是:deletedelete[] 是两个不同的运算符,具有可能不同的实现。他们可以使用不同的分配策略(请参阅下面问题 #3 的答案)。

  1. Why delete intArPtr1 gives an error on run-time? Why doesn't it delete all elements but first from the array?

您必须向 delete 传递一个分配有 new 的指针。确切的指针。不是 new 分配的内存区域中的指针,这是行不通的。它必须是指向区域开始的相同指针。

  1. How does C++'s runtime knows size of the allocated array (for delete [])? Is it stored somewhere?

一个常见的分配器策略是在分配区域之前存储分配的字节数。 delete 然后会获取您传递给它的指针,向左查找 4 或 8 个字节,并将该整数解释为该区域的大小。如果您将指向其他地方的指针传递给它,它的回溯策略就会失败。

C++ 语言没有指定如何跟踪内存分配,因此这是一个实现细节。不同的标准库、编译器和操作系统会以不同的方式执行此操作。我所描述的只是一种可能的机制。

进一步阅读:

关于c++ - 为什么我不能通过指针从数组中删除非第一个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32875930/

相关文章:

c++ - 使用 LatentSVMDetector 从视频中检测对象

c++ - 如何针对自定义 CUDA 安装使用 OpenCL 构建 GDAL?

c++ - 类的大小与封闭模板类的大小

javascript - 如何使用不在 Angular 中另一个数组中的值过滤 ng-repeat?

javascript - 如何从 Javascript 中的数字数组中删除前导零

iphone - 需要澄清 NSAutoreleasePool

c++ - 如何在不使用任何不必要空间的情况下合并三个排序数组?

javascript - 平均查找器始终打印 “0”

java - 如果我对对象的引用超过 32 位所能解释的,会发生什么情况?

iphone - -[UIImage绘制矩形:]/CGContextDrawImage() not releasing memory?