1 c++ memory-management undefined-behavior dynamic-memory-allocation delete-operator
假设我分配了一些内存来存储 int 值,如下所示:
int *p=new int;
Run Code Online (Sandbox Code Playgroud)
在这里,我使用运算符创建了所需的内存new,并分配了该内存块的地址,以便我可以访问该内存块。
现在我可以控制存储在该内存块中的内容。
但是当我写下这样的声明时:
delete p;
Run Code Online (Sandbox Code Playgroud)
我们说我已经删除了动态分配的内存。
但是,如果我真的delete释放了该内存,那么在delete?但我能够使用相同的指针变量访问该内存块。那么如果删除后还能访问该内存块,那么删除该内存块的目的是什么呢?
这是一些示例代码:
#include <iostream>
using namespace std;
int main(void)
{
int *p;
p=new int;
*p=10;
cout << *p << endl;
delete p;
//here look we can still access that block of memory using the same pointer variable
//But we did not created the memory block after deletetion
cout << *p << endl;
*p=20;
cout << *p << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,“删除/释放动态分配的内存”这句话意味着什么?
其他答案说取消引用指针delete是未定义的行为是正确的。但我认为了解正在发生的事情而不是简单地说“任何事情都可能发生”是有用的。
当您delete指向指针时,程序会执行以下几个步骤:
第二步,根据实现,可能实际上将内存块返回给操作系统,或者可能只是简单地标记该块可用于后续分配,或者执行其他操作。显然,在您的情况下,该块只是简单地标记为空闲,但没有返回到操作系统。进一步的分配可能会返回该块内的地址,然后未定义的行为可能会从“工作正常”变为“工作奇怪”。
但即使您仍然可以通过已删除的指针访问该对象,编译器仍然可以假设该对象不再存在,并依赖于此进行一些优化。这可能会以非常意外且看似不合逻辑的方式破坏您的程序,因此您最好避免未定义的行为。