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

如何修复C++内存泄漏?类A管理B及shared_ptr向量致内存持续增长

为什么你的代码会出现内存占用持续增长的情况?

首先,我先帮你拆解下代码的预期行为:每次循环调用A::returnA()时,会创建一个临时的A对象,当循环迭代结束时,这个临时对象会被销毁——它的析构函数~A会被调用,同时销毁成员变量b(A::B实例),以及vector<shared_ptr<B>>;vector里的shared_ptr引用计数归零后,也会自动释放它指向的B实例。按道理来说,不应该出现内存泄漏。

那为什么你会看到内存持续增长呢?大概率是这两个原因:

1. 内存分配器的缓存机制(最可能)

C++的内存分配器(比如glibc的malloc)会把释放的内存缓存起来,不会立刻还给操作系统,而是留着供后续的内存分配使用。这样做是为了提升分配效率,避免频繁向操作系统申请/释放内存的开销。

所以你看到的“内存占用增长”,其实是分配器缓存的内存,并不是真正的内存泄漏——当缓存达到一定规模后,内存占用就会稳定下来,不会持续增长。

2. 未确认析构函数是否真的被调用

你可以先运行代码,看看控制台有没有输出~A和~B:

  • 如果能看到这些输出,说明对象确实在被销毁,那肯定不是泄漏,只是分配器缓存的问题;
  • 如果看不到输出,那可能是编译器做了某些优化(比如把整个循环优化掉了),或者临时对象的生命周期被意外延长了。这种情况下,你可以尝试关闭编译器优化(比如用-O0参数)再测试。

如何验证是否真的有内存泄漏?

你可以给B类加一个静态计数器,跟踪构造和析构的次数:

class A {
public:
    static A returnA(){ return A(); }
    class B {
    public:
        static int alive_count;
        B() { alive_count++; }
        ~B() { 
            cout << "~B" << endl; 
            alive_count--;
        }
    };
    B b;
    vector<std::shared_ptr<B>> v;
    A(){ 
        std::unique_ptr<B> b2 = make_unique<B>(); 
        v.emplace_back(make_shared<B>()); // 这里建议用make_shared代替new,更安全
    };
    ~A() { cout << "~A" << endl; }
};

int A::B::alive_count = 0;

int main() {
    int i = 0;
    while(1){ 
        A::returnA(); 
        if (++i % 1000 == 0) {
            cout << "Alive B instances: " << A::B::alive_count << endl;
        }
    }
}

如果运行后alive_count始终保持为0,说明所有B实例都被正确销毁了,完全没有内存泄漏。

另外,你也可以用专业的内存检测工具,比如valgrind,它能准确告诉你是否存在真正的内存泄漏,以及泄漏的位置。

代码优化建议

  • 用make_shared<B>()代替new B()来初始化shared_ptr,这样可以避免内存分配的额外开销,也更安全;
  • 如果不想让A被拷贝,可以把returnA()改成返回unique_ptr<A>,这样能减少不必要的拷贝操作,提升效率:
    static std::unique_ptr<A> returnA(){ 
        return std::make_unique<A>(); 
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:37:30