运行时检测内存删除

代码:

int *ptr = new int[10]; int *q = ptr; delete q; 

工作正常没有任何问题(没有运行时错误)。

但是,下面的代码:

 int *ptr = new int[10]; int *q = ptr; q++; delete q; 

导致运行时错误。

我正在使用Microsoft Visual Studio-8和Win-7作为平台。

我无法弄清楚为什么在第二种情况下会出现运行时错误?

您的代码导致未定义的行为 。 未定义行为意味着任何事情都可能发生,行为不能被定义。 该程序运行纯粹的运气,其行为无法解释。

基本上,

如果您正在使用new动态内存分配,您必须使用delete来释放它。

如果你正在用new[]分配动态内存,你必须使用delete[]来释放它。

通过任何地址delete未被new返回的是未定义的行为。
这里是标准的引用。

按照C ++ 03标准§3.7.4.2-3:

如果释放函数通过抛出异常终止,则行为是未定义的。 提供给释放函数的第一个参数的值可能是一个空指针值; 如果是这样,并且如果释放函数是在标准库中提供的函数,则该调用不起作用。 否则,在标准库中提供给operator delete(void*)的值应该是之前调用operator new(std::size_t)operator new(std::size_t, const std::nothrow_-t&) ,在标准库中提供给操作符delete[](void*)的值应该是先前调用operator new[](std::size_t)operator new[](std::size_t, const std::nothrow_t&)在标准库中。

在C ++中,最好使用智能指针而不是原始指针来使用RAII(SBRM) ,原始指针会自动处理内存释放。

这里有两个错误:

  1. 您不能delete未被new返回的指针。
  2. 你不能deletenew[]返回的指针 – 你需要使用delete[]

所以,第一个片段只能巧合使用,而且不会因为使用原始类型而出现错误。 如果是UDT,析构函数将不会运行。

此外,你应该使用容器和智能指针,而不是原始的newdelete

因为你必须通过新的删除结果。 这就是事情的工作,即新/删除的API合同。

因为你改变了q点的地址,然后试图删除它。

你只应该尝试delete任何new回报给你。 任何其他的是未定义的行为。