【问题标题】:C++ delete pointer twice [duplicate]C ++删除指针两次[重复]
【发布时间】:2014-09-28 01:47:30
【问题描述】:

我知道当两个 指针寻址同一个动态分配的对象。如果delete 是 应用于其中一个指针,然后对象的内存返回到 免费商店。如果我们随后删除第二个指针,那么 free 商店可能已损坏。

但为什么这段代码不会导致运行时错误?

 string *str_1 = new string;
  auto str_2 = str_1;
  *str_1 = "AAA";
  cout<<*str_2<<endl;
  delete str_1;
  delete str_2;  // No Error

    // Prints AAA

【问题讨论】:

  • 你处于未定义行为的土地上。这就是为什么。
  • 未定义的行为意味着它只有在你足够幸运的情况下才会崩溃
  • 删除后能打印str_1和str_2的值吗?
  • @chiel 是的,我可以,但它是未定义的,这意味着这块内存可能被覆盖,随时可能出错
  • str_1 和 str_2 的值不是未定义的。只有他们指向的记忆可能不再存在。

标签: c++ pointers


【解决方案1】:

我尝试在 Visual Studio 中执行此操作。有两种情况:

1)

delete p;
delete p;

这可以正确编译,但在您运行程序时会导致调试断言失败,因为您正在尝试删除已删除且不再属于您的内存位置。

2)

delete p;
p = NULL;
delete p;

这可以正确编译并正常运行。没有错误。尝试打印 p 删除前后。

【讨论】:

    【解决方案2】:

    我在 g++ 4.9.1 中编译了这个程序,它给了我一个运行时错误:

    *** Error in `./t': free(): invalid pointer: 0xbfa8c9d4 ***
    

    你试图释放已经释放的东西。因此,错误。

    【讨论】:

      【解决方案3】:

      如果您在 Visual Studio 调试模式下编译程序,则第一次删除应将内存设置为 0xFEEEFEEE(请参阅此question) - 但是您的进程仍可访问该地址,因此不太可能导致异常。链接到像 BoundsChecker 或 Purify 这样的产品我相信会检查这些字节模式,以便它可以检测到对已删除内存的访问。

      【讨论】:

        【解决方案4】:

        在第二个删除命令之后没有定义程序的行为,所以你真的不知道会发生哪个错误并在终端中打印。

        【讨论】:

          【解决方案5】:

          两次删除相同的内存是未定义的行为。任何事情都可能发生,包括什么也没有。它可能例如稍后导致崩溃。

          【讨论】:

          • ...因为这就是某些人会不顾一切的地方(“见鬼,对我有用,不会那么糟糕”),我通常会添加“...或者它可能会格式化您的硬盘”。 ;-)
          • 如果程序稍后崩溃,有什么想法可以调试吗?我遇到了这种情况,不得不撤消所有更改,然后才发现我将其删除了两次。想知道是否有更好的方法。
          • 为什么它是未定义的行为?它只是试图删除指定内存位置中的任何内容吗?
          猜你喜欢
          • 1970-01-01
          • 2020-09-14
          • 1970-01-01
          • 2011-12-21
          • 1970-01-01
          • 1970-01-01
          • 2018-05-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多