2012-09-03 158 views
0

伴侣的雷告诉我,我有内存泄漏在此代码C++内存泄漏固定

Base 
{ 
    public: 
     vector<Foo*> fooes; 
}; 

Derived : public Base 
{ 
    public: 

     Derived () 
     { 
      for (int i = 0 ; i < 10 ; i++) 
      { 
        this.fooes.push_back (new Foo()); 
      } 
     }; 

}; 

但他是一个非常忙碌的人,他也帮不了我,所以我问你,内存泄露?我该如何解决它? 据我所知,内存泄漏是,我不删除对象,通过new Foo()创建的,所以我就可以在析构函数添加到Base,并明确fooes载体,对不对?

Base 
{ 
    public: 
     vector<Foo*> fooes; 
     ~Base () 
     { 
      this->fooes.clear(); 
     }; 

}; 

的问题是:

  1. 这是一个正确的内存泄漏修复?

  2. 在Derived的析构函数之前调用Base的析构函数吗?

  3. 将同时删除Base或我必须手动删除类的所有成员fooes vertor被自动删除?

+0

什么是'Foo'?它是多态的吗? (和不相关的:'Base'的析构函数应该是虚拟的) –

+2

你只是不应该使用哑指针的向量。要么使用智能指针的矢量,要么使用专门设计用来容纳指针的集合。 (还有其他可怕的方式会失败,如复制分配或复制结构。) –

+3

如果你或你的伴侣没有时间,那么你绝对不能使用裸指针和'new'。制作一个'std :: vector >',继续繁忙的生活而不用担心内存管理。 –

回答

7

1)这是一个正确的内存泄漏修复?

不,你必须遍历元素并手动delete他们。

2)将立足的析构函数的派生,或不析构函数之前被调用?

否(假设您正在删除Derived对象)。

3)在删除Base时是否会自动删除fooes矢量,或者我必须手动删除该类的所有成员?

是&没有。因为它是自动管理的载体本身将被删除,其成员不得:

~Base () 
{ 
    for (size_t i = 0 ; i < fooes.size() ; i++) 
    delete fooes[i]; 
}; 

你应该为每一个newnew[]一个deletedelete[]分别。

一个更好的替代品,这一切都是使用智能指针。

+0

我们可以扩展向量类,以便它自己删除?例如:vector_e.del_n_clear(); –

+0

@tuğrulbüyükışık标准容器不打算延长。 –

+0

@tuğrulbüyükışık你可以做的是做一个免费的函数,它将一个向量作为参数并删除它的项目:'template clearVector(T&vect){....};'。 –

3

您需要遍历在矢量所有的指针和清除之前删除它们。矢量将清除指针,但它不会清除他们指出,除非你自己做的内存或更改您的载体使用像一个shared_ptr。如果您的载体是对象的载体,那么你就不会有内存泄漏,但由于该元素是已经通过new被分配的指针,你需要释放内存 - 矢量不会自动为您代劳。

+0

vector :: clear向量的所有元素被删除:它们的析构函数被调用,然后它们被从vector容器中移除,留下容器大小为0. – Kolyunya

+3

@Kolyunya动态分配对象的析构函数不是自动调用。 –

+1

@Kolyunya是的,它会销毁指针,但是这不会释放它们指向的内存 - 当不使用智能指针时必须手动完成 – mathematician1975

1

有一个在代码示例没有内存泄漏,只是一个类定义。如果一个程序创建了一个类型为Derived的对象并将其销毁,那么可能(见下文)是内存泄漏。但是,如果一个程序创建一个类型为Derived的对象,销毁它所保存的所有Foo对象,然后删除原始对象,则可能不会有内存泄漏。

内存泄漏很少能单独分析;它们是整个程序的属性。可以修改该类以删除Foo对象,但这可能会强加一个新的设计约束,而这并非意图。例如,Foo对象可能会将自己注册到内部容器中,并要求所有这些对象都会一直存在,直到程序结束;根据需要,删除Derived析构函数中的对象将是错误的。

现在,这大都是假设;我不会抱怨某人增强Derived的析构函数以删除所有Foo对象 - 这可能是正确的做法。但总有一点疑问......