当我们在指向未分配 new 运算符的对象的指针上使用 delete 时会发生什么

What happens when we use delete on a pointer to an object not allocated with new operator?

本文关键字:delete 什么 指针 对象 我们 运算符 new 分配      更新时间:2023-10-16

下面的代码编译正常,但不执行

#include <iostream>
using namespace std;
int main()
{
    int *a;
    int b = 5;
    a = &b;
    cout << *a << endl;
    delete a;
    return 0;
}

编辑:

int main()
{
    int *a = 0;
    delete a;
    return 0;
}

这工作正常。为什么会这样?

编辑后,您只有一种未定义行为的情况: delete你没有获得的记忆new.

空指针上的delete保证不会造成伤害。但是,您之前未分配或删除的内存上的delete是未定义的。我知道的实现以某种访问违规的方式退出您的程序。

"

未定义的行为"意味着您所做的没有保证的后置条件。

人们经常会说,"编译器"选择发生的事情。实际上,编译器将编译它,堆管理器在运行时决定如何处理您调用无效删除调用的情况。

尽管这里的情况在编译器级别看起来微不足道,但在许多情况下,这样做根本不超出了编译器的范围。

它会导致未定义的行为

  1. 您正在使用未分配的内存来存储数据
  2. 您正在删除未分配的内存

这两个因素都最有可能导致"访问冲突"崩溃。

但是,由于行为未定义,应用程序可以工作。

您正在尝试写入未由您分配的内存位置。

*a = 5;

然后尝试删除未由您分配的内存

删除A;

它具有未定义的行为。

您有三种未定义行为的情况:第一种是使用未初始化的指针a取消引用和赋值,第二种是打印a时的取消引用,最后一种是删除a时。

在尚未分配新的指针或空指针的指针上调用 delete未定义的行为 草案C++标准部分5.3.5 删除2段说(强调我的):

[...]在第一种替代方法(delete 对象)中,delete 的操作数的值可以是空指针值、指向由上一个 new-expression 创建的非数组对象的指针,也可以是指向表示此类对象的基类的子对象 (1.8) 的指针(条款 10)。否则,行为未定义。

与所有未定义的行为一样,一切皆有可能,该程序甚至看起来工作正常,但结果不可靠。

您正在尝试删除堆栈内存。在堆栈内存中,如果您尝试删除它,将发生未定义的行为。

因为堆内存分配不会传染。