【发布时间】:2016-12-01 02:54:37
【问题描述】:
在测试我对堆栈的实现(即使用链表)时,我发现了一件有趣的事情。有一个测试代码可以重现它:
#include <iostream>
using namespace std;
struct Node {
int val;
Node *prev;
};
int main() {
Node *first = new Node;
first->val = 20;
first->prev = NULL;
cout << "first:" << first << endl;
Node *p = new Node;
p->val = 40;
p->prev = first;
delete p;
cout << "p->val:" << p->val << endl;
cout << "p->prev:" << p->prev << endl;
}
输出:
first:0x22cfc20
p->val:0
p->prev:0x22cfc20
但是如果我像这样交换struct Node 定义中的元素顺序:
struct Node {
Node *prev;
int val;
};
输出将是
first:0x195dc20
p->val:40
p->prev:0
当然,在这两种情况下它都是未定义的行为,但也许它存在一些合理的解释,为什么它会以这种方式工作?还是只是随机的?我尝试多次运行代码,但每次都给出相同的输出(特定地址值除外)并且从未崩溃。
【问题讨论】:
-
未定义的行为并不真正有趣。
-
“未定义行为”表示“未定义行为”。您观察到的实际行为在很大程度上取决于您的实现的堆管理例程。由于您甚至没有指定您的操作系统,因此无法在此处收集更多信息。
-
一旦您更改编译器选项(如优化),您的程序可能会开始表现不同。然后你会发现寻找未定义行为的原因是徒劳的。在某些时候,您会意识到这是在浪费时间,而且您还有更好的事情要做(例如开发应用程序)。
标签: c++ pointers memory-management undefined-behavior