1

我知道我应该使用std::vector或其他替代方法,但有些东西我不明白指针。

当我们创建一个指针数组时:

int* a = new int[100];

它应该分配一个空间100 * sizeof(int),不是吗?

当我们不再需要它时,我们会:

delete [] a;

1.

这是错误的:

delete a;

但是当我实际这样做时(曾经在娱乐程序中意外),似乎没有触发运行时错误(与下面的第 3 部分不同)并且程序正常运行(尽管可能存在内存泄漏)。为什么?它实际上是否删除(释放)了数组的第一个元素?


2.

根据StackOverflow 上的一个问题delete[]知道它需要删除的数组的大小。

但是当我删除错误的东西时会发生什么?(它会导致运行时错误......它在 codepad.org 上显示memory clobbered before allocated block以及Debug Assertion FailedVS2010 中的某些内容。)为什么不直接删除(免费)元素 1 到 99?

delete [] &a[1]; // or
delete [] (a + 1);

3.

下面的代码也显示了memory clobbered before allocated block. 但是为什么不直接删除(释放)元素 99?为什么它会导致错误,但delete a就像第 1 部分一样?

delete &a[99]; //or
delete (a + 99);

C++ 标准是否真的说明了上述事情会发生什么?

4

2 回答 2

6
  1. 根据 C++ 标准,删除new[]使用 using分配的对象delete是未定义的行为。任何事情都可能发生——从“什么都没有”到破坏你的堆得面目全非。说在这种情况下究竟删除了什么是没有意义的,因为它严重依赖于系统。

  2. 删除“错误的东西”是未定义的行为。通常,这会破坏您的堆,因为分配器的常见实现期望某些值将存储在您传递用于释放的地址之前。这绝不是一个标准,所以再一次,任何事情都可能发生。

  3. 它不会删除元素 99,因为它从未分配元素 99:它分配了一个包含 100 个项目的数组,而不是单个int; 它希望您一次释放所有 100 个项目 - 您不能以任何其他方式释放它。

于 2013-01-01T06:47:19.993 回答
4

为什么?它实际上是否删除(释放)了数组的第一个元素?

不,从技术上讲,它导致了未定义的行为。这意味着任何事情都可能发生。

使用newor的规则new []非常简单:

  • 如果您使用过,new必须使用delete,如果使用过,new []必须用于delete[]释放。
  • 您应该将 or 返回的地址new传递new []deleteor delete []

你不遵守规则,你最终会出现未定义的行为。

为什么这一切?

因为 C++ 标准是这么说的。
该标准为您提供了通过动态内存分配来管理对象的生命周期和内存的功能,作为回报,您可以签订合同以遵循标准要求获得此功能的规则。
你违反了合同,你将受到惩罚。

简而言之,

“权力越大责任越大”

于 2013-01-01T06:42:38.207 回答