为什么在 C++ 中删除操作后仍然可以访问已释放的动态分配的内存?

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)

在这种情况下,“删除/释放动态分配的内存”这句话意味着什么?

Rus*_*lan 6

其他答案说取消引用指针delete是未定义的行为是正确的。但我认为了解正在发生的事情而不是简单地说“任何事情都可能发生”是有用的。

当您delete指向指针时,程序会执行以下几个步骤:

  1. 调用指针引用的对象的析构函数
  2. 调用内存管理器的函数,该函数将执行释放内存所需的任何簿记操作。

第二步,根据实现,可能实际上将内存块返回给操作系统,或者可能只是简单地标记该块可用于后续分配,或者执行其他操作。显然,在您的情况下,该块只是简单地标记为空闲,但没有返回到操作系统。进一步的分配可能会返回该块内的地址,然后未定义的行为可能会从“工作正常”变为“工作奇怪”。

但即使您仍然可以通过已删除的指针访问该对象,编译器仍然可以假设该对象不再存在,并依赖于此进行一些优化。这可能会以非常意外且看似不合逻辑的方式破坏您的程序,因此您最好避免未定义的行为。