2016-02-18 108 views
1
int main() 
{ 
    A* x = new B(10, 20); 
    x->opt1(); 
    delete x; 
    return 0; 
} 

int main() 
{ 
    B x(10, 20); 
    return 0; 
} 

因此,第一個有內存泄漏,我明白,因爲x是一個A對象,指向一個B對象。如果A不是指針,它仍然會有內存泄漏?內存泄漏C++指針

爲什麼第二個函數沒有內存泄漏?我們不需要刪除x?

class A 
{ 
    private: 
     int* a; 
    public: 
     A(int size) { 
      a = new int[size]; 
     } 
     ~A() { 
      if (a) { 
       delete [] a; 
      } 
     }; 
     virtual void opt1() { 
      cout << "A::opt1()" << endl; 
     } 
}; 

class B : public A 
{ 
    private: 
     float* b; 
    public: 
     B(int size1, int size2) : A(size1) { 
      b = new float[size2]; 
     } 
     ~B() { 
      if(b){ 
       delete [] b; 
      } 
     } 
     virtual void opt1() { 
      cout << "B::opt1()" << endl; 
     } 
}; 
+1

確實'A'有虛擬析構函數嗎? –

回答

3

第一次有內存泄漏,據我所知,因爲x是一個A對象,指向一個B對象。

不,沒有內存泄漏如果AB有明確的繼承關係。如:

class A { 
public: 
    virtual ~A() {} 
}; 

class B : public A { 
}; 

爲什麼第二功能不會有內存泄漏?

因爲x是在棧,它不需要和不能叫delete分配。 x將自動銷燬。

我們不需要刪除x?

只有由new創建的對象需要delete

EDIT

對於你的AB代碼,第一殼體會導致內存泄漏,因爲A(基類)的析構函數不是虛擬。對於

A* x = new B(10, 20); 
delete x; 

只有A析構函數會被調用的B析構函數將不會被調用,這意味着float* bB不會被釋放。

如果您想以這種方式使用它們,即通過指向基類的指針刪除派生類的實例,這是個壞主意。

請參閱When to use virtual destructors?

+0

哎呀,我很抱歉,忘了自己包括類。它看起來像A有繼承關係和析構函數,這就是爲什麼我很困惑。 – Brian

+0

@Brian由於'A'的析構函數不是**虛擬**,所以第一種情況會導致內存泄漏。看到我編輯的答案。 – songyuanyao

2

第二,new沒有顯式調用,儘管該項目的構造函數是。但是這個變量會自動超出範圍,因爲自動調用的析構函數可以防止任何形式的泄漏,前提是析構函數被正確寫入以抵消對象內部的任何內部分配。

我會認爲第一個例子不會是內存泄漏,但也許有一些導致問題的基礎類的優點。