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

含指针的C++类链式调用get()触发运行时错误,如何基于指针修复?

问题分析与修复方案

这个问题的根源其实是对拷贝构造函数的误用,咱们一步步拆解并解决:

问题核心原因

当你调用v.get().get()时,第一个get()会返回一个临时的X对象,接着对这个临时对象调用get(),此时在get()函数里创建ret对象会触发拷贝构造函数。原拷贝构造函数一开始就执行delete[] ptr;,但此时正在被构造的新对象(ret)的ptr成员是未初始化的野指针(VS环境下用0xcccccccc标记未初始化的栈内存),直接delete一个未初始化的指针必然触发运行时错误。

另外原类还有个隐藏问题:没有定义析构函数,用new[]分配的内存永远不会被释放,会造成内存泄漏。

基于指针的修复实现

我们需要遵循C++的三法则(Rule of Three):当类自定义了析构函数、拷贝构造函数其中一个时,必须同时定义另外两个。下面是修复后的完整代码:

class X {
private:
    int *ptr;
public:
    // 默认构造函数
    X() {
        ptr = new int[2];
        ptr[0] = 0;
        ptr[1] = 0;
    }

    // 带参数的构造函数
    X(int a, int b) {
        ptr = new int[2];
        ptr[0] = a;
        ptr[1] = b;
    }

    // 修正后的拷贝构造函数:无需提前delete,新对象的ptr还未分配内存
    X(const X &val) {
        ptr = new int[2]; // 先为新对象分配内存
        ptr[0] = val.ptr[0]; // 拷贝源对象的值
        ptr[1] = val.ptr[1];
    }

    // 添加析构函数,释放动态分配的内存
    ~X() {
        delete[] ptr;
        ptr = nullptr; // 置空指针,避免后续误操作野指针
    }

    // 重载赋值运算符(三法则要求),处理对象间赋值逻辑
    X& operator=(const X &val) {
        if (this == &val) { // 自我赋值检查,防止释放自身内存后拷贝失败
            return *this;
        }
        delete[] ptr; // 释放当前对象的旧内存
        ptr = new int[2]; // 分配新内存
        ptr[0] = val.ptr[0]; // 拷贝值
        ptr[1] = val.ptr[1];
        return *this;
    }

    X get() {
        X ret(ptr[0], ptr[1]);
        return ret;
    }
};

关键修复点说明

  • 修正拷贝构造函数:去掉了错误的delete[] ptr;,因为拷贝构造是创建全新对象,此时对象的ptr还未初始化,根本不需要释放内存,直接分配新内存并拷贝值即可。
  • 添加析构函数:负责释放new[]分配的数组内存,避免内存泄漏,同时将指针置空防止野指针问题。
  • 重载赋值运算符:处理对象间的赋值操作,先做自我赋值检查,再释放旧内存、分配新内存并拷贝值,最后返回自身引用,避免浅拷贝导致的重复释放问题。

修复后,v.get().get()就能正常运行,同时解决了内存泄漏的潜在问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:02:05