You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

显式调用构造函数后,已释放动态内存仍可访问的问题咨询

为什么析构函数释放内存后,仍能读取到原指针的值?

你遇到的情况是典型的未定义行为,核心原因是临时对象生命周期结束后,保存的指针变为野指针,看似能读到旧值只是偶然现象,完全不可靠。

问题分析

  1. 临时对象的生命周期
    Node()是临时对象,它的生命周期仅存在于int *ptrOfClass = Node().ptr;这一行表达式执行期间。该行代码执行完毕后,临时对象会被立即销毁,析构函数被调用,ptr指向的动态内存被delete释放。

  2. 野指针与未定义行为
    此时ptrOfClass保存的是已被释放的内存地址,成为野指针。操作系统释放内存后,不会立刻清除内存中的数据,只是将其标记为可分配状态。在没有其他操作覆盖这块内存前,你可能还能读取到旧值,但这属于未定义行为——程序随时可能崩溃、输出错误结果,或者表现出不可预测的行为,完全依赖于当前内存状态。

  3. 代码中的错误
    你错误地保存了临时对象的内部指针,却未保证对象的生命周期覆盖指针的使用周期。对象销毁后,其管理的动态内存被释放,指针自然失效。

修正方案

方案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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 05:36:13