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

类析构函数中指针置NULL引发C++内存泄漏的解决方法

内存泄漏问题分析与修复方案

先看你提供的类代码:

头文件

class dbsk2d_ishock_node : public dbsk2d_ishock_elm{ 
protected: 
    dbsk2d_ishock_edge* _cShock; 
    //Some other variables 
public: 
    dbsk2d_ishock_node (int newid, double stime, vgl_point_2d<double> Or); //Constructor 
    virtual ~dbsk2d_ishock_node (); //Destructor 
    //Some other functions 
};

实现文件

//Constructor 
dbsk2d_ishock_node::dbsk2d_ishock_node (int newid, double stime, vgl_point_2d<double> Or) 
    : dbsk2d_ishock_elm (newid, stime) 
{ 
    _cShock = NULL; 
    //Some other variables 
} 

//Destructor 
dbsk2d_ishock_node::~dbsk2d_ishock_node () { 
    _cShock = NULL; 
    //Some other variables 
}

第一个问题:只把指针置为NULL会导致内存泄漏吗?

绝对会。这里的核心问题是:如果_cShock指向的是用new在堆上分配的dbsk2d_ishock_edge对象,仅仅把指针设为NULL,只是让这个指针不再指向那块内存,但堆上的内存本身根本没有被回收。每次创建dbsk2d_ishock_node对象并分配_cShock的内存后,析构时只置空指针,这块内存就永远留在堆里了——次数多了,堆内存被耗尽,程序自然会因为内存占用过高崩溃。

修复方案

根据_cShock的所有权情况,有两种常见的修复方式:

1. 如果当前类是_cShock的唯一所有者

如果dbsk2d_ishock_node对象负责创建_cShock,并且没有其他对象共享这个指针,那么直接在析构函数里释放内存即可:

dbsk2d_ishock_node::~dbsk2d_ishock_node () { 
    delete _cShock; // 真正释放堆内存
    _cShock = NULL; // 可选:置空防止野指针(现代C++里不是必须,但老代码习惯保留)
    // 处理其他变量
}

⚠️ 注意:如果_cShock是数组类型(比如new dbsk2d_ishock_edge[5]),一定要用delete[] _cShock;,否则会触发未定义行为。

2. 如果_cShock是多对象共享的

如果有多个对象都需要访问_cShock,直接delete会导致重复释放的问题。这种情况下,推荐用智能指针来自动管理内存,比如std::shared_ptr:

首先修改头文件,引入智能指针:

#include <memory> // 必须包含这个头文件

class dbsk2d_ishock_node : public dbsk2d_ishock_elm{ 
protected: 
    std::shared_ptr<dbsk2d_ishock_edge> _cShock; // 替换原始指针
    //Some other variables 
public: 
    dbsk2d_ishock_node (int newid, double stime, vgl_point_2d<double> Or); 
    virtual ~dbsk2d_ishock_node () = default; // 智能指针会自动处理,析构函数可以默认生成
    //Some other functions 
};

然后修改构造函数:

dbsk2d_ishock_node::dbsk2d_ishock_node (int newid, double stime, vgl_point_2d<double> Or) 
    : dbsk2d_ishock_elm (newid, stime), _cShock(nullptr) 
{ 
    // 处理其他变量
}

这样,当最后一个持有_cShock的对象被销毁时,shared_ptr会自动释放对应的内存,完全不需要手动管理,从根源上避免内存泄漏和重复释放的问题。

额外注意点

如果你的类里有成员函数会重新给_cShock分配内存,一定要确保在赋值新地址前先释放旧内存(用原始指针的话),或者直接用智能指针赋值即可——智能指针会自动处理旧内存的释放。


内容的提问来源于stack exchange,提问作者Shashwat Gupta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:52:41