C++类公有指针成员值异常求助:调用函数时值莫名变化
问题根源与解决方案:悬空指针导致的未定义行为
兄弟,我一眼就瞅出你这问题的症结了——这是典型的**悬空指针(Dangling Pointer)**搞的鬼!
先给你拆解下问题:你在构造函数里定义了一个局部变量int b = 23;,这个变量的生命周期只局限在构造函数执行的这段时间里。当构造函数跑完,b就会被销毁,它占用的内存空间会被系统回收,后续可能被其他操作覆盖。但你把类的指针成员a指向了&b(也就是这个局部变量的地址),这就导致a变成了悬空指针:指针本身的地址确实不会变,但它指向的内存已经不属于你的变量了,之后任何时候访问*a都是未定义行为,你看到的那些奇怪值就是内存被其他操作改写后的结果。
先贴出你给出的代码方便对照:
class whathappened { public: int * a; whathappened(); void print(); }; whathappened::whathappened() { int b = 23; a = &b; // 这里把指针指向了局部变量b,大错特错! } void whathappened::print() { cout << a << " " << *a << endl; }
下面给你几个靠谱的解决办法,按需选:
方法一:动态分配堆内存
把内存分配到堆上,这样它的生命周期由你手动控制,不会随着构造函数结束而销毁。记得要写析构函数释放内存,避免内存泄漏:class whathappened { public: int * a; whathappened(); ~whathappened(); // 新增析构函数 void print(); }; whathappened::whathappened() { a = new int(23); // 在堆上分配内存并初始化值为23 } whathappened::~whathappened() { delete a; // 释放堆内存 } void whathappened::print() { cout << a << " " << *a << endl; }方法二:放弃指针,用普通成员变量
如果你的场景不需要用指针,直接把a改成普通的int成员变量是最简单的,完全避开指针相关的坑:class whathappened { public: int a; // 替换指针为普通int whathappened(); void print(); }; whathappened::whathappened() { a = 23; } void whathappened::print() { cout << &a << " " << a << endl; // 要打印地址的话用&a即可 }方法三:使用智能指针(推荐C++11及以上版本)
如果必须用指针,强烈推荐用智能指针来自动管理内存,不用手动写delete,能有效避免内存泄漏和悬空指针问题:#include <memory> // 记得包含智能指针的头文件 class whathappened { public: std::unique_ptr<int> a; // 用unique_ptr替代裸指针 whathappened(); void print(); }; whathappened::whathappened() { a = std::make_unique<int>(23); // 分配内存并初始化 } void whathappened::print() { cout << a.get() << " " << *a << endl; // get()获取裸指针地址 }
最后再提醒一句:永远不要让指针指向局部变量的地址!局部变量出了作用域就会被销毁,指针就变成悬空的了,这种未定义行为的表现五花八门,这次只是值乱了,运气差的话直接程序崩溃都有可能。
内容的提问来源于stack exchange,提问作者snowingmignight
相关产品推荐
相关产品推荐

