我的C ++代码中是否存在内存泄漏?

时间:2017-06-12 02:35:00

标签: c++ memory-leaks

#include <iostream>

class B {
public:
    B() {}
    void p() const { std::cout << "B::p\n"; }
    void q() const { std::cout << "B::q\n"; }

    int b;
};

class D : public B { 
public:
    D() {}

    virtual void p() const { std::cout << "D::p\n"; }
    virtual void q() const { std::cout << "D::q\n"; }

    int d;
};

int main(int argc, char const *argv[])
{
    B b;
    D d;

    B* pb = new B;
    B* pd = new D;
    D* pd2 = new D;

    b.p(); b.q();
    d.p(); d.q();

    pb->p(); pb->q();
    pd->p(); pd->q();
    pd2->p(); pd2->q();

    delete pb;
    delete pd;
    delete pd2;

    return 0;
}

好像delete pd中存在内存泄漏。我想pd不是指向D的指针,所以当我delete它时,它不会调用D的析构函数,而是B的析构函数{1}}。但是,我不知道具体原因。谁能帮帮我?感谢。

3 个答案:

答案 0 :(得分:3)

您的代码中可能存在内存泄漏。但同样地,可能没有。

如评论中所述,此序列

B* pd = new D;
delete pd;
代码中的

(与您提供的所有其他代码无关)给出了未定义的行为,因为B没有virtual析构函数。

当行为未定义时,任何事情都可能发生,包括内存泄漏或您可能或可能无法想象的任何其他内容。

如果为virtual声明B析构函数,并定义它以使其不会泄漏内存(例如virtual ~B() {}),那么您的代码将具有明确定义的行为。使用运算符new正确销毁了使用运算符delete创建的所有对象,因此 - 如果B具有虚拟析构函数 - 它们都不会导致内存泄漏。

答案 1 :(得分:0)

你怎么知道D的析构函数没有被调用?您的示例代码甚至没有析构函数。实际上,它不会像评论中所指出的那样调用D的析构函数。在基类中没有虚拟析构函数并不好。

尝试以下示例,

#include <iostream>

class B {
public:
    B() {}
    virtual ~B() { std::cout << "B::dtor\n"; }
    void p() const { std::cout << "B::p\n"; }
    void q() const { std::cout << "B::q\n"; }

    int b;
};

class D : public B {
public:
    D() {}
    virtual ~D() { std::cout << "D::dtor\n"; }

    virtual void p() const { std::cout << "D::p\n"; }
    virtual void q() const { std::cout << "D::q\n"; }

    int d;
};

int main(int argc, char const *argv[])
{
    B b;
    D d;

    B* pb = new B;
    B* pd = new D;
    D* pd2 = new D;

    b.p(); b.q();
    d.p(); d.q();

    pb->p(); pb->q();
    pd->p(); pd->q();
    pd2->p(); pd2->q();

    delete pb;
    delete pd;
    delete pd2;

    return 0;
}

对于你的问题,你的实现有一个漏洞,因为pd被删除了可能不会调用用D的dtor编写的内存清理。

答案 2 :(得分:-1)

B* pb = new B;
//B::B()

B* pd = new D;
//B::B()   <-- constructor called
//D::D()   <-- constructor called

D* pd2 = new D;
//B::B()
//D::D()

....
pd->p(); pd->q();
//B::p
//B::q
....

delete pb;
//~B::B()

delete pd;
//~B::B()  <-- leaks here

delete pd2;
//~D::D()
//~B::B()

你应该使用关键字&#34; virtual&#34;对于B类的析构函数:

private:
virtual ~B() {}