我有一个 Node 类。成员是一个整数 id 和一个指向下一个节点的指针。我按如下方式实现了构造函数和析构函数。
#include <iostream>
class Node {
public:
int id;
Node *next;
Node() : id(0), next(nullptr) {}
explicit Node(int id) : id(id), next(nullptr) {}
~Node() {
std::cout << (*this) << " destructed \n";
delete next;
next = nullptr;
}
friend std::ostream &operator<<(std::ostream &os, const Node &node) {
os << "Node(" << node.id << ")";
return os;
}
};
int main() {
Node *node0;
Node *node1;
node0 = new Node(0);
node1 = new Node(1);
node0->next = node1;
delete node0; // outputs Node(0) destructed\nNode(1) destructed
node0 = nullptr;
std::cout << (nullptr == node0) << '\n'; // outputs 1
std::cout << (nullptr == node1) << '\n'; // outputs 0
std::cout << *node1 << " \n"; // outputs Node(8430)
return 0;
}
我认为node1应该已经指向NULL,因为在调用node0的析构函数时,它的next被删除并指向NULL,但输出表明node1显然是Node(8430)并且不是nullptr。
我知道当取消引用空指针时可能会导致未定义的行为。我该如何修改这个程序,使得调用delete node0后,node1也可以变成NULL?
你所期望的与此类似:
void foo(int* ptr) {
delete ptr;
ptr = nullptr;
}
int main() {
int * x = new int;
foo(x);
assert( x == nullptr); // NOPE !!
}
ptr
是 x
的副本。 delete ptr
删除动态分配的int
。这不会以任何方式影响 x
的值。调用 x
后,foo
仍然具有相同的值。它不再是一个有效的指针了。它所指向的地址不再包含int
。
在您的代码中
node0->next = node1;
创建了指针的副本。然后在 node0
的析构函数中删除 node0->next
指向的节点,但这对 main 中的指针没有影响。
TL;DR:不要混淆指针和受指点。
delete x
删除x
指向的对象。如果你复制一个指针,你就会有两个完全独立的指针,它们只指向同一个对象。