这是要把前几年积累的C++的节操给丢光吗

本文通过一个C++程序实例展示了由于未使用虚析构函数而导致的内存泄漏问题,并提供了修复方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

是java把人给养废了还是c++的坑太多?


#include <iostream>
#include <string>
#include <vector>

using namespace std;

class A {
    public:
        string str;
        A(const string &s):str(s){}
        ~A() {
            cout << "destruct A\n";
        }

};

class Base {
};
class B: public Base{
    public:
        A a;
        vector<int> vec;
        B(const vector<int> &v, A &a1):vec(v), a(a1){}
};

int main() {
    //A *a = new A("hello");
    //delete a;
    vector<int> vec(100,5);
    A a("aaa");
    Base *b = new B(vec,a);
    delete b;
    return 0;
}

上面的程序有问题吗?



很严重的内存泄露。

C++的多态是通过虚函数实现的,要是不把Base的析构函数设为virtual的,在delete时,就调用base的析构函数了,而不是调用B的析构,然后B中有成员变量vec就没法释放了。

解决办法很简单,就是在base中添加个virtual的析构函数就行了。


先回忆下类的构造顺序,先构造基类,再构造派生类

具体的讲就是在构造类的时候,先构造基类,在构造当前类的成员变量,最后调用当前类的构造函数


析构的时候顺序相反


看上面的程序,delete b的时候,因为Base没有virtual的析构函数,所以,只会调用Base的析构函数,而不会调用B的析构函数,因为B的成员变量是在调用B的析构函数只会再析构的,所以,B的成员变量也不会被析构


刚开始看B类,是两个非指针类型的成员变量,所以,即使没有调用B类的默认生成的析构函数,只调用Base类的析构函数,应该也不会有内存泄露。但是,要注意的是,string和vector内部实现都只是一个指针,然后向堆中申请内存,如果不调用默认生成的析构函数,那么也不会析构string和vector,造成内存泄露。


解决方案:如果有继承的话,基类一定要有虚析构函数



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值