【问题标题】:What actually happens in C++ when I call "delete?" [closed]当我调用“删除”时,C++ 中实际发生了什么? [关闭]
【发布时间】:2013-11-29 04:21:05
【问题描述】:

我注意到,每次我在二叉搜索树类中删除一个节点时,它都会简单地将其替换为 0。换句话说,假设我有一个节点树,当在预购遍历中打印时会产生“五、三、四、六。”假设我调用 remove 函数来删除 3(这个函数所做的就是沿着树搜索,直到找到所需的节点,然后在该节点上调用 delete)。当我使用预订遍历再次打印时,出现的是“5、0、4、6”。根据我对删除的了解,它释放了已使用的内存,因此指针现在指向任何内容。它不应该只是给出一个分段错误而不是打印一个 0 吗?

【问题讨论】:

标签: c++ pointers segmentation-fault delete-operator dynamic-allocation


【解决方案1】:

Delete 只是调用它所调用的对象的析构函数,并将分配的内存发送回堆。您描述的行为特定于您的实现。

也许您的预购遍历在找到空节点时会打印“0”,或者您的析构函数可能存在问题,如果不看代码就很难判断。

【讨论】:

    【解决方案2】:

    delete 将内存释放回内存管理器,因此,您无法再对所述内存的内容做出任何保证。它可能仍然包含您节点的内容,但也有可能内存被覆盖。

    即使在调用 delete 之后,您的指针仍然是有效的指针。只是你不能再保证所述内存的内容是有效的。

    关于潜在的段错误,如果您的代码尝试取消引用NULL 指针,则只会在这种情况下发生段错误。您的指针不是 NULL,因此不会发生段错误。

    【讨论】:

      【解决方案3】:

      在C++编程语言中,delete操作符调用给定参数的析构函数,并将new分配的内存返回给堆"

      int * x = NULL;
      x = new int(6);
      cout << *x << endl;
      delete x;
      cout << *x;
      

      上面的代码在堆上创建了一个 int,因为我假设你正在打印它然后删除它。删除后 x 指向的内存返回到开销并分配给某个值,但指针仍然有效。所以上面的代码打印出来:

      6 然后是一些随机数

      【讨论】:

        【解决方案4】:

        未定义行为意味着该行为未定义,而不是它应该崩溃。您希望所有未定义的行为快速而严重地崩溃,但情况并非总是如此。

        有多种原因可以解释您遇到的行为,其中第一个也是最简单的原因是,通常分配器不适用于任何随机大小,而是当您分配一个小块时它可能会出现在多个页面上从与其他分配相同的页面,当您释放它时,它可能不会返回给操作系统。操作系统可以标记一个内存页面是可访问的(用于读取、写入或执行),一旦它将一个页面交给您的应用程序,整个页面就可以是可读/可写的。如果您取消分配内存,在您的操作系统中实现malloc/free 可能不会将内存归还给操作系统,而是将其保留在应用程序中。该内存超出了您的应用程序的范围,但它可能不会被标记为不可访问。您可能能够在不崩溃的情况下对其进行读取或写入,但无法保证会发生什么。

        更改运行时配置中的某些参数可能会强制释放内存并导致崩溃,或者内存可能未释放,但用于不同的对象,读取可能不是读取节点,而是读取任何其他随机对象,写入可能会破坏一些不相关代码的状态...

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-09-19
          • 2016-09-17
          • 1970-01-01
          • 2018-06-07
          • 2018-08-12
          • 2011-03-31
          • 1970-01-01
          相关资源
          最近更新 更多