这是个问题,我应该弄清楚错误是什么。
#include <cstdio>
struct Node {
int data;
Node* next;
};
void foo(Node* n) {
delete n->next;
}
Node* create(int x, Node* n) {
Node* n1 = new Node();
n1->data = x;
n1->next = n;
return n1;
}
int main(void) {
Node* n1 = create(1, NULL);
Node* n2 = create(2, n1);
foo(n2);
Node* n3 = create(3, NULL);
n1->data = 42;
printf("%d\n", n3->data);
delete n2;
delete n3;
return 0;
}
问题是,代码将打印数字42,而不是预期的3。
我通过使用调试器将其范围缩小到以下问题:
在create方法内部调用行Node* n3 = create(3, NULL)
时,第一行创建的n1实际上与首先创建然后删除的n1相同。这与创建n2时发生的情况相反,后者在create函数中的n1实际上有一个新地址。
因此,出于某种原因,似乎在foo
中执行删除操作之后,new Node()
操作不再返回新地址。
仅供参考,当交换foo(n2)
和Node* n3 = create(3, NULL)
行时,该代码将打印3,这是预期的行为。
谢谢
答案 0 :(得分:3)
调用foo(n2)
时,n1
和n2->next
都指向同一个Node
对象。先foo
个对象,再delete
个对象。此时,n1
和n2->next
都指向无效的位置。这意味着,当您以后尝试分配给n1->data
时,程序的行为将变得不确定。在这种特定情况下,n3
指向的对象最终位于n1
最初指向的对象所在的位置,而您最终通过n1
更改了该对象。虽然不能保证。从无到有,程序崩溃都可能发生。
答案 1 :(得分:0)
您的写入无效。 foo(n2)
有效地调用delete n1
,然后分配另一个Node
;在您的情况下,新分配的内存与n1
具有相同的地址(自从释放内存以来,该地址现在可用)。
如果您在valgrind
下运行程序,它将报告无效的写操作。