Zha*_*man 1 c++ pointers linked-list nullptr
我有Node课。成员是int id, 和指向下一个节点的指针:Node* next。我按如下方式实现了构造函数和析构函数:
#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;
}
Run Code Online (Sandbox Code Playgroud)
我认为node1应该已经指向 ,nullptr因为在调用 的析构函数时node0,它的下一个被删除并指向nullptr,但输出表明node1显然是 Node(8430) 而不是nullptr。
我知道取消引用 a 时nullptr可能会导致未定义的行为。我怎样才能修改这个程序,以便在调用delete之后node0,node1也可以变成nullptr?
您所期望的与此类似:
void foo(int* ptr) {
delete ptr;
ptr = nullptr;
}
int main() {
int * x = new int;
foo(x);
assert( x == nullptr); // NOPE !!
}
Run Code Online (Sandbox Code Playgroud)
ptr是 的副本x。delete ptr删除动态分配的int. x这不会以任何方式影响 的价值。x调用后仍然具有相同的值foo。它不再是一个有效的指针了。它所指向的地址不再存在int。
或者更简单:
int* a = new int;
int* b = a;
delete a;
a = nullptr;
assert( b == nullptr ); // NOPE !!!
Run Code Online (Sandbox Code Playgroud)
其实你的误解可以追溯到一个更简单的例子:
int a = 42;
int b = a;
a = 0;
assert( b == 0); // NO !!
Run Code Online (Sandbox Code Playgroud)
对于指针来说,这没有什么不同。
在您的代码中node0->next = node1;创建了指针的副本。然后在析构函数中node0删除 指向的节点node0->next,但这对 main 中的指针没有影响。
TL;DR:不要混淆指针和受指点。delete x删除 指向的对象x。如果复制一个指针,就会有两个完全独立的指针指向同一个对象,分配nullptr给其中一个指针不会对另一个指针产生影响。
| 归档时间: |
|
| 查看次数: |
175 次 |
| 最近记录: |