当前位置:   article > 正文

C++笔记3:基类指针delete子类对象的内存泄漏问题

C++笔记3:基类指针delete子类对象的内存泄漏问题

根据《effective C++》第7章所述,new的一个子类对象赋值给基类指针delete的时候为了防止子类的析构函数没有调用要在基类的析构函数加上virtual 关键字:

#include <stdint.h>
#include <iostream>
#include <iomanip>
#include <vector>

class A
{
public:
    A() : a(0)
    {
    }
    virtual  ~A()
    {
        std::cout << "delete A" << std::endl;
    }

private:
    int a;
};

class B : public A
{
public:
    B() : A(), b(1), c(2) {}
    ~B()
    {
        std::cout << "delete B" << std::endl;
    }

private:
    int b;
    int c;
    // members
};
int main()
{
    A *a1 = new B;
    delete a1; 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

成功析构!
在这里插入图片描述

然而根据《more effective C++》第三章所说,用一个数组存放基类的指针指向子类的对象,使用delete []来释放子类的对象会出现内存泄漏(crash):

#include <stdint.h>
#include <iostream>
#include <iomanip>
#include <vector>

class A
{
public:
    A() : a(0)
    {
    }
    virtual ~A()
    {
        std::cout << "delete A" << std::endl;
    }

private:
    int a;
};

class B : public A
{
public:
    B() : A(), b(1), c(2) {}
    ~B()
    {
        std::cout << "delete B" << std::endl;
    }

private:
    int b;
    int c;
    // members
};
int main()
{
    A *a1 = new B[2];
    delete[] a1;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

结果是什么也没有输出。

一个朴素的解决办法是不要使用new一个指针数组,改用vector或array来存放指针:

#include <stdint.h>
#include <iostream>
#include <iomanip>
#include <vector>

class A
{
public:
    A() : a(0)
    {
    }
    virtual ~A()
    {
        std::cout << "delete A" << std::endl;
    }

private:
    int a;
};

class B : public A
{
public:
    B() : A(), b(1), c(2) {}
    ~B()
    {
        std::cout << "delete B" << std::endl;
    }

private:
    int b;
    int c;
    // members
};
int main()
{

    std::vector<A *> v;
    v.push_back(new B);
    v.push_back(new B);
    for (int i = 0; i < v.size(); ++i)
        delete v[i]; 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

这样即使用一个基类指针指向子类指针也能正确地析构
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/煮酒与君饮/article/detail/864268
推荐阅读
相关标签
  

闽ICP备14008679号