使用基类指针删除派生类时出现内存泄漏

时间:2011-03-03 21:31:52

标签: c++ memory-leaks polymorphism

我遇到内存泄漏问题。我有一个基类指针。从中,我使用new来分配不同的派生类。然后,当我尝试delete带引用的类(不是类型转换)时,我得到内存泄漏。我研究了这个问题,发现我应该在基类中添加一个虚拟析构函数,但是我尝试了这个并且仍然有内存泄漏;也就是说,根据我的任务管理器,使用基类指针每次分配和删除派生类时,内存使用量会继续增加。我试图使它成为一个抽象的析构函数,并在派生类中添加了析构函数,但是我得到了一个未定义的引用错误。我还尝试将指针类型转换为delete的派生类指针,但显然这会使程序崩溃。

有谁知道我应该怎么做?

示例代码:

class A {
public:
  A();
  ~A() {};
  virtual ~A();      /*or*/
  virtual ~A()=0;    /*or*/
                     /*or nothing?*/
}

class B: private A {
public:
  B();
  ~B() {};           /*this?*/
                     /*or nothing?*/
}

4 个答案:

答案 0 :(得分:5)

你确定内存泄漏有多确定?通常,任务管理器在这里没有太大帮助,因为它无法分辨出实际分配了多少属于您的进程的内存。即使释放的内存仍然属于您的进程,并且可能在以后由内存管理(通常类似malloc的系统库)使用。

使用诸如mallocdebug,valgrind,purify等工具来查明是否存在内存泄漏。这些工具将用一个新工具替换malloc实现,该工具跟踪已分配的内存并报告在进程终止时未释放的内存。

注意:在大多数系统上,在进程退出之前,从进程中释放的内存不会返回到系统。但是,它可以在同一个过程中进行新的分配。

答案 1 :(得分:3)

如果你有一个虚拟析构函数,你的子类的析构函数都将被调用。不需要用抽象的解构器或任何东西做任何神秘的魔法。

我认为内存泄漏位于对象内部。也许你在B(或A的?)构造函数中调用new(),但你不删除它。没有看到更多的代码,我只能说“你的析构函数设置很好”。

答案 2 :(得分:3)

使用virtual ~A();

如果允许virtual ~A()=0,我会感到惊讶。

使用此代码:

A* base = new B();
delete base;

B的析构函数然后将被调用。

如果你真的还在泄漏记忆,那么你在其他地方又有另一个泄漏。

答案 3 :(得分:0)

您可以使用:

virtual ~A(){}

virtual ~A()=0; 

// as long as there is also:
A::~A(){}  // inline in the header file or non-inline in the cpp file.

这意味着:

A* base;
...
delete base;

将以正确的顺序调用派生类的所有析构函数。

请注意,如果在没有其他成员函数是纯虚拟的情况下需要拥有抽象基类时,纯虚拟析构函数virtual ~A()=0;会很有用。