显式调用构造函数后,已释放动态内存仍可访问的问题咨询
为什么析构函数释放内存后,仍能读取到原指针的值?
你遇到的情况是典型的未定义行为,核心原因是临时对象生命周期结束后,保存的指针变为野指针,看似能读到旧值只是偶然现象,完全不可靠。
问题分析
临时对象的生命周期
Node()是临时对象,它的生命周期仅存在于int *ptrOfClass = Node().ptr;这一行表达式执行期间。该行代码执行完毕后,临时对象会被立即销毁,析构函数被调用,ptr指向的动态内存被delete释放。野指针与未定义行为
此时ptrOfClass保存的是已被释放的内存地址,成为野指针。操作系统释放内存后,不会立刻清除内存中的数据,只是将其标记为可分配状态。在没有其他操作覆盖这块内存前,你可能还能读取到旧值,但这属于未定义行为——程序随时可能崩溃、输出错误结果,或者表现出不可预测的行为,完全依赖于当前内存状态。代码中的错误
你错误地保存了临时对象的内部指针,却未保证对象的生命周期覆盖指针的使用周期。对象销毁后,其管理的动态内存被释放,指针自然失效。
修正方案
方案1:延长对象生命周期
创建具名对象,让它的生命周期覆盖指针的整个使用阶段:
#include<bits/stdc++.h> using namespace std; class Node{ public: int *ptr; Node(){ ptr = new int(5); cout<< ptr <<endl; cout<<"Constructor Called\n"; } ~Node(){ delete ptr; ptr = nullptr; cout<<"Destructor Called\n"; } }; int main(){ Node node; // 具名对象,生命周期持续到main函数结束 int *ptrOfClass = node.ptr; cout<<"Hi\n"; cout<< *ptrOfClass <<endl; return 0; }
方案2:使用智能指针管理内存
用C++标准库的智能指针(如unique_ptr)代替裸指针,自动管理内存生命周期,从根源避免野指针问题:
#include<bits/stdc++.h> using namespace std; class Node{ public: unique_ptr<int> ptr; Node(){ ptr = make_unique<int>(5); cout<< ptr.get() <<endl; cout<<"Constructor Called\n"; } ~Node(){ // unique_ptr会自动释放内存,无需手动delete cout<<"Destructor Called\n"; } }; int main(){ // 通过move转移智能指针的所有权,避免临时对象销毁时释放内存 unique_ptr<int> ptrOfClass = move(Node().ptr); cout<<"Hi\n"; cout<< *ptrOfClass <<endl; return 0; }
内容的提问来源于stack exchange,提问作者Aditya Patel
相关产品推荐
相关产品推荐

