当我调用对象的方法时,对象的成员会发生变化

My objects' members change when I call their methods

本文关键字:对象 变化 成员 调用 方法      更新时间:2023-10-16

我在C++中有一个对象,其中有几个属性最初设置为nullptr,这个想法是我可以判断何时到达我迄今为止定义的边缘。例如,我可以将Node链接在一起链接到一个链表中,并通过与nullptr进行比较来检测列表的末尾:

class Node{
public:
Node* next;
bool val;
Node(bool v){val=v; next=nullptr;}
void append(bool v){
if (next==nullptr){
next=&Node(v);
}else{
next->append(v);
}
}
}

问题是我不断收到读取访问违规。当我在 Visual Studio 中逐行执行时,我在每次失败之前都会看到同样的事情:在一个堆栈帧中,next设置正确,0x00000000用于自己的后继帧,但是当我调用next->append(v);时,突然next是一个随机指针,如 0x01010101 或 0x00000001,它不是nullptr,因此代码尝试在其上调用append并死亡,因为该地址没有Node. 回顾一下:*next.next==nullptr,但是在打电话next.append(v);之后,有些事情发生了变化并next!=nullptr了。

这里的解决方案是动态分配该对象。您正在使用的临时值超出了下一行的范围,并且对该行的任何引用都将失效,这意味着您的next指针现在是垃圾。

简单的解决方法是:

void append(bool v) {
if (next == nullptr) {
next = new Node(v);
} else {
next->append(v);
}
}

使用new进行分配并适当放置该值的地方。

请务必注意,当您分配new时,您的代码负责释放带有delete的内存。换句话说,您现在有义务创建一个析构函数来解除所有分配。

值得注意的是,您的构造函数没有正确表达,它应该如下所示:

Node(bool v) : val(v), next(nullptr) { }

其中使用构造函数列表。这可确保不会首先默认值,然后通过有效地重新定义默认值来立即分配值。