C++嵌套类中解引用指针异常问题求助
嵌套类指针解引用异常原因分析与修复
问题根源:临时对象销毁导致指针悬空
你代码里的野指针问题,核心是临时mid对象销毁后,low里的parent指针指向了已释放的内存,具体执行流程如下:
top构造函数中,(mid(this))创建了一个临时mid对象,这个对象的生命周期仅局限于当前赋值语句,语句执行完就会被销毁。- 临时
mid构造时,会初始化自身的child(low对象),这个low的parent指针指向临时mid的地址(this指向临时对象)。 - 执行
child = (mid(this)).child;时,是把临时mid的low对象浅拷贝给top的child——拷贝的只是指针值,所以top的child里的parent依然指向那个临时mid。 - 赋值语句结束,临时
mid被销毁,其内存被回收,此时top的child里的parent就成了野指针。 - 调用
t.child.addToVal()时,parent->parent的第一步就访问了已销毁的mid内存,触发解引用异常。
对象创建过程的细节拆解
当你创建top t时,执行顺序是:
- 先默认初始化
top的成员mid::low child:调用low的无参构造,parent被设为nullptr。 - 进入
top的构造函数:- 创建临时
mid对象:先默认初始化mid的low child(parent为nullptr),再执行mid构造函数——把parent设为top的地址,然后执行child = low(this);,此时这个low的parent指向临时mid。 - 把临时
mid的child赋值给top的child:浅拷贝后,top的child的parent指针直接继承了临时mid的地址。
- 创建临时
- 临时
mid对象销毁,内存释放,top的child的parent变为无效指针。 - 调用
t.child.addToVal()时,访问野指针触发未定义行为。
修复方案
方案一:持有持久的mid对象,避免临时对象
让top直接持有一个mid成员,其生命周期和top一致,low的指针指向这个持久对象:
class top { public: int val = 0; class mid { public: top* parent; class low { public: mid* parent = nullptr; void addToVal() { parent->parent->val += 1; } low(mid* Parent) : parent(Parent) {} low() {} }; low child; mid(top* Parent) : parent(Parent), child(this) {} }; mid child_mid; // 持久化的mid对象,和top同生命周期 mid::low& child; // 用引用关联mid的low,避免拷贝指针 top() : child_mid(this), child(child_mid.child) {} }; int main() { top t; t.child.addToVal(); }
方案二:简化指针依赖,让low直接持有top指针
如果业务允许,跳过mid的指针中转,让low直接保存top的指针,从根源避免中间指针悬空:
class top { public: int val = 0; class mid { public: top* parent; class low { public: top* top_parent = nullptr; void addToVal() { top_parent->val += 1; } low(top* tp) : top_parent(tp) {} low() {} }; low child; mid(top* Parent) : parent(Parent), child(Parent) {} }; mid::low child; top() : child(this) {} }; int main() { top t; t.child.addToVal(); }
内容的提问来源于stack exchange,提问作者The Armored Panda
相关产品推荐
相关产品推荐

