是否有必要在删除之前将类中的所有指针都指定为NULL?我的意思是,例如,对于删除二叉搜索树中的节点的函数的以下片段,
1
Node *temp = parent->left;
parent->left = temp->left;
delete temp;
2
Node *temp = parent->left;
parent->left = temp->left;
temp->left = NULL;
delete temp;
是行
temp->left = NULL;
必要?有些教程可以做到,有些则没有。
答案 0 :(得分:4)
可能没有必要。删除后,代码无法安全取消引用temp
。正如Ralph Tandetzky所指出的,如果Node
有一个在其left
成员上运行的析构函数,那么它是有效的
NULL
其成员的另一个可能的好处是更可预测地捕获无效访问。
答案 1 :(得分:4)
取决于。如果Node
的析构函数删除了子节点,那么这是必要的。如果没有,则不需要该行。然而,一些教程可能仅仅为了促进良好的编程风格而包含它。如果您向程序引入了一个错误并在删除它后使用指针,那么使用空指针将为您提供错误消息而不是未定义的行为。如果您想更严格地遵循此样式,您可能还需要添加行temp = NULL;
。
答案 2 :(得分:1)
不,这不是必需的,但如果left
指针指向的内存属于对象,则应该删除依次。
答案 3 :(得分:1)
没有线
temp-> left = NULL;
没有必要。在许多情况下,如果你强制自己在每次删除后添加这一行会很有帮助,因为如果程序崩溃并且你看到指针设置为零,你将能够轻松识别错误。
答案 4 :(得分:1)
这不是绝对必要的,这是一个旨在帮助调试的措施。想象一下,你没有NULL
就离开了那个指针(例如,在一个链表中),不知怎的,你进入已被释放的内存,但其内容尚未被删除。然后存在这样的危险:你可以跟踪那个指针,而不知道它是否仍然存在,并且可能在它已被删除时尝试删除该存储器。
所以,这只是安全,而不是旨在实现任何功能的东西。
还有另一种(补充)方法来实现相同的方法:检测被访问的内存是否已被删除。例如:
class Node {
public:
Node()
{ status = 0xf00dbeef; }
~Node()
{ status = 0xdeadbeef; }
// ...
private:
int status;
bool isAlive() const
{ return ( status == 0xfoodbeef ); }
};
这样,您可以始终确保使用正确分配的内存,即a)未释放,b)实际存储Node
对象。
希望这有帮助。