C++ “动态内存分配”;删除“;

C++ “动态内存分配”;删除“;,c++,heap,dynamic-memory-allocation,delete-operator,C++,Heap,Dynamic Memory Allocation,Delete Operator,如果我为int对象动态分配内存位置,如下所示: int*x=新的int 完成后,要释放堆上的内存,我将执行以下操作: 删除x 现在,如果我做了而不是,请执行以下操作: x=NULL x是否指向另一个地址更新:另一个而不是多个 假设我没有做x=NULL,并且做了另一个删除x,会发生什么 删除x(除了=NULL——在我看来,这是一种糟糕的做法)之后,您对它所做的任何操作都是未定义的 双重删除=灾难 注意:某些运行时系统将 保护你免受某些非常简单的伤害 双重删除的情况。取决于 关于细节,如果你 正好在

如果我为
int
对象动态分配内存位置,如下所示:

int*x=新的int

完成后,要释放堆上的内存,我将执行以下操作:

删除x

现在,如果我做了而不是,请执行以下操作:

x=NULL

x
是否指向另一个地址更新:
另一个
而不是
多个

假设我没有做
x=NULL
,并且做了另一个
删除x,会发生什么

  • 删除
    x
    (除了
    =NULL
    ——在我看来,这是一种糟糕的做法)之后,您对它所做的任何操作都是未定义的
  • 双重删除=灾难
  • 注意:某些运行时系统将 保护你免受某些非常简单的伤害 双重删除的情况。取决于 关于细节,如果你 正好在其中一个上面跑步 系统,如果没有人部署 您在另一个系统上的代码 以不同的方式处理事情,如果你 正在删除不存在的内容 有一个析构函数,如果你不这么做 两者之间有什么重要的区别吗 删除,如果没有人更改 你的代码可以做一些有意义的事情 在两次删除之间,如果 线程调度程序(通过它可以 很可能无法控制!)不会 碰巧在两者之间交换线程 删除和如果,和如果,和如果。所以 回到墨菲:因为它可能出错, 会的,到时候会出问题的 最糟糕的时刻

  • 删除
    x
    (除了
    =NULL
    ——在我看来,这是一种糟糕的做法)之后,您对它所做的任何操作都是未定义的
  • 双重删除=灾难
  • 注意:某些运行时系统将 保护你免受某些非常简单的伤害 双重删除的情况。取决于 关于细节,如果你 正好在其中一个上面跑步 系统,如果没有人部署 您在另一个系统上的代码 以不同的方式处理事情,如果你 正在删除不存在的内容 有一个析构函数,如果你不这么做 两者之间有什么重要的区别吗 删除,如果没有人更改 你的代码可以做一些有意义的事情 在两次删除之间,如果 线程调度程序(通过它可以 很可能无法控制!)不会 碰巧在两者之间交换线程 删除和如果,和如果,和如果。所以 回到墨菲:因为它可能出错, 会的,到时候会出问题的 最糟糕的时刻


    删除
    后,指针通常仍包含(现在可用)内存的地址。第二个
    delete
    给出了未定义的行为,所以不要这样做。

    delete
    之后,指针通常仍然包含(现在空闲)内存的地址。第二个
    delete
    给出了未定义的行为,所以不要这样做。

    它将调用未定义的行为。如果不执行
    x=NULL
    ,则
    x
    将指向无效的内存位置,如果尝试使用该位置,将导致未定义的行为。

    它将调用未定义的行为。如果不执行
    x=NULL
    ,则
    x
    将指向无效的内存位置,如果尝试使用该位置,将导致未定义的行为。

    对已删除的内存调用delete将导致未定义的行为。通常,您的程序会崩溃

    删除x后,它将指向的位置是“依赖于编译器的”。在调用delete之前,大多数编译器都会让它指向它所在的位置。但该内存地址不再有效,因此不应被调用


    出于同样的原因,如果需要,必须非常谨慎地使用“删除此项”。:-)

    对已删除的内存调用delete将导致未定义的行为。通常,您的程序会崩溃

    删除x后,它将指向的位置是“依赖于编译器的”。在调用delete之前,大多数编译器都会让它指向它所在的位置。但该内存地址不再有效,因此不应被调用

    出于同样的原因,如果需要,必须非常谨慎地使用“删除此项”。:-)

    类型:

    int main(){
      int* i = new int;
      std::cout << i << std::endl;
      delete i;
      std::cout << i << std::endl;
      delete i;
    }
    
    intmain(){
    int*i=新的int;
    标准::cout类型:

    intmain(){
    int*i=新的int;
    
    std::cout第二次删除未定义


    作为旁注,有一些工具可以检测双重删除。最好的方法之一是。

    第二次删除未定义


    作为补充说明,有一些工具可以检测双重删除。最好的工具之一是。

    最后一句话不一定是真的:有些编译器会“保护”您不这样做,因此它可能看起来“有效”。但这仍然是未定义的行为,这仍然是一个坏主意。测试它并不是获得答案的正确方法。@Code Gray:这不是测试,而是演示。第一句话不一定是真的,这就是我为什么说“可能取决于环境”。最后一句话不一定是真的:一些编译器将“保护”你不能这样做,所以它可能看起来“有效”。但这仍然是未定义的行为,这仍然是一个坏主意。测试它不是获得答案的正确方法。@Code Gray:这不是测试,而是演示。第一句话不一定是真的,这就是我为什么说“可能取决于环境”.但是,当我执行
    删除
    操作时,我不是在删除
    指针
    本身吗?你怎么说“如果不执行x=NULL,那么x将指向无效的内存位置”?Thanks@user588855:假设删除前
    x
    是0x11111111。因此,当您执行
    delete x;
    时,此内存位置是空闲的。但由于您dn未将
    x
    设置为
    NULL
    它仍具有值
    0x11111111
    ,该值是一个已释放的内存位置。正在尝试读取/写入此位置