C++删除指针两次问题

7
我知道当两个指针指向同一个动态分配的对象时,可能会发生"重复删除同一内存"错误。如果对其中一个指针应用delete,则该对象的内存将返回给自由存储区。如果随后删除第二个指针,则可能会破坏自由存储区。
但是为什么这段代码不会导致运行时错误呢?
 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

2
你处于未定义行为的领域。这就是原因。 - Samuel
11
未定义行为意味着如果你足够幸运,它只会崩溃。 - Bryan Chen
在删除之后,您能打印出str_1和str_2的值吗? - Chiel
@chiel 是的,我可以,但它是未定义的,这意味着这块内存可能会被覆盖,并且随时会发生错误。 - Person.Junkie
str_1和str_2的值并不是未定义的,只是它们所指向的内存可能已经不存在了。 - Chiel
5个回答

23

对同一内存进行两次删除操作是未定义的行为。任何事情都有可能发生,包括什么也不会发生。例如,这可能导致稍后崩溃。


2
由于这是某些人变得鲁莽的时候(“嘿,对我来说可以,不会那么糟糕”),我通常会添加“...或者它可能会格式化您的硬盘”。;-) - DevSolar
1
有没有什么想法可以调试程序是否会在以后崩溃?我曾经遇到过这种情况,不得不撤销所有更改,才发现我删除了两次。想知道是否有更好的方法来解决这个问题。 - user1198065
为什么会出现未定义行为?它只是尝试删除指定内存位置中的任何内容吗? - cjsimon
1
@cjsimon 未定义行为通常与速度有关。定义发生的情况将意味着运行时检查需要消耗 CPU 周期。编译器可以自由处理任何方式或根本不处理(通常是这种情况,特别是在选择优化级别时)。它很可能会盲目地更新,就像一个有效的对象存在一样,或者快速崩溃,因为跟踪这些事情的代码可能会假设 delete 只被调用来自 new 的指针。 - user904963

2
我用g++ 4.9.1编译这个程序,但运行时出现了错误:
*** Error in `./t': free(): invalid pointer: 0xbfa8c9d4 ***

您正在尝试释放已经被释放的内容。因此,出现了错误。

2
我在Visual Studio中尝试过这个。有两种情况:
1)
delete p;
delete p;

这段代码可以编译通过,但在运行程序时会出现调试断言失败的情况,因为您试图删除已经被删除且不再属于您的内存位置。

2)

delete p;
p = NULL;
delete p;

这段代码可以正确编译和运行,没有错误。尝试在删除之前和之后打印p。


0

在第二个删除命令之后,您的程序的行为未定义,因此您不知道将发生哪种错误并在终端中打印。


0
如果您在Visual Studio调试模式下编译程序,那么第一个删除应该将内存设置为0xFEEEFEEE(请参见此问题)-但是该地址仍然可以被您的进程访问,因此不太可能引发异常。像BoundsChecker或Purify这样的产品链接会检查这些字节模式,以便它可以检测已删除内存的访问。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接