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

咨询C++类中指针数据成员的delete位置:手动释放时机该如何选择

关于C++类中指针成员的delete时机问题

嘿,针对你的疑问,咱们来好好捋清楚手动管理类内动态内存的正确姿势~

首先明确核心原则:谁用new分配了内存,谁就要负责用delete释放,而且释放时机必须是在这块内存不再被使用之后,同时要避免重复释放或野指针问题。

回到你的代码,sum是类的私有成员指针,属于对象的一部分,所以最安全的释放位置是在类的析构函数里。因为当对象的生命周期结束时(比如你main函数里的obj离开main的作用域时),析构函数会自动被调用,这时候释放sum指向的内存,就能完美避免内存泄漏。

给你修改后的代码示例,加上析构函数:

#include<iostream>
class test {
private:
    int* sum{new int};
public:
    // 析构函数:对象销毁时自动触发
    ~test() {
        delete sum; // 在这里释放sum指向的堆内存
        sum = nullptr; // 可选操作,避免后续误操作野指针
    }

    int addFunc(int num1 = 5, int num2 = 2) {
        *sum = num1 + num2;
        return *sum;
    }
    void print() {
        std::cout << *sum << std::endl;
    }
};
int main() {
    test obj;
    obj.addFunc();
    obj.print();
    // 当obj离开这个作用域时,析构函数自动执行,内存被正确释放
}

这里要提醒你几个容易踩的坑:

  • 绝对不要在addFunc或者print这类成员函数里delete sum,因为delete之后sum就变成了野指针,后续再调用任何访问*sum的函数都会导致未定义行为(比如程序崩溃)。
  • 别忘了处理拷贝构造和拷贝赋值的问题!C++默认的拷贝行为是浅拷贝,也就是说如果你拷贝一个test对象,两个对象会共享同一个sum指针。当其中一个对象销毁时delete了这块内存,另一个对象再访问就会出大问题。解决方法有两种:
    1. 直接禁用拷贝(如果你的类不需要被拷贝的话):
      // 在类的public区域添加
      test(const test&) = delete;
      test& operator=(const test&) = delete;
      
    2. 实现深拷贝(需要拷贝对象时):
      // 拷贝构造函数:为新对象分配独立的内存,拷贝值而非指针
      test(const test& other) {
          sum = new int;
          *sum = *other.sum;
      }
      
      // 拷贝赋值运算符:处理自赋值,确保内存安全
      test& operator=(const test& other) {
          if (this != &other) {
              *sum = *other.sum; // 直接拷贝值,因为当前对象已经有分配好的内存
              // 或者如果需要重新分配内存的话:
              // delete sum;
              // sum = new int(*other.sum);
          }
          return *this;
      }
      

最后再总结一下:

  • 手动管理类内动态分配的成员指针,析构函数是最可靠的释放时机,确保对象生命周期结束时内存被正确回收。
  • 不要在普通成员函数中随意delete指针,除非你能100%确定后续不会再用到这块内存,并且要及时将指针置为nullptr。
  • 拷贝/赋值的问题一定要重视,否则很容易出现双重释放或野指针的崩溃问题。

内容的提问来源于stack exchange,提问作者Amin Khormaei

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 22:12:48