2012-08-01 47 views
1

假設我們有一個名爲memoryCounter的類,它試圖捕獲MyClass類造成的內存泄漏。等量的構造函數和析構函數調用確保沒有內存泄漏?

class memoryCounter 
{ 
public: 
    static int MyClassCount; 
}; 
int memoryCounter::MyClassCount = 0; 

我們還假設我們把在構造和MyClass析構函數以下行(以及任何其他的構造,它有,也假設我們不修改MyClassCount其他地方的構造函數/析構函數外):

MyClass() 
{ 
    memoryCounter::MyClassCount++; 
} 
virtual ~MyClass() 
{ 
    memoryCounter::MyClassCount--; 
} 

現在,我們可以絕對肯定如果memoryCounter::MyClassCount包含零,那麼我們分配這個內存遠遠被釋放,並沒有泄漏?或者當變量包含零時會出現這種情況,但是會分配我們沒有空閒的內存(請考慮'MyClass'是基類還是派生類的情況)?

+0

如果您希望即使對於派生類也可以使此工作變爲虛擬。 – 2012-08-01 10:42:06

+1

不需要虛擬析構函數。如果有人擔心通過指向'memoryCounter'的指針刪除,您可以私下繼承(或保護)並公開公開計數。 (不是說OP甚至建議'memoryCounter'應該通過繼承來使用 - 這不是通常的CRTP計數器。) – 2012-08-01 10:54:36

回答

2

如果計數爲零破壞,那麼有沒有MyClass實例。無論MyClass對象是完整對象還是基類子對象,或者是成員子對象,它都適用。這並不一定意味着沒有內存泄漏,因爲MyClass本身可能會泄漏內存。

需要注意的是默認生成的拷貝構造函數。你假設「任何其他的構造函數都會增加你的全局計數」,但是很容易遺漏未出現在代碼中的構造函數。你可以在這裏應用三個規則 - 你定義了一個析構函數,所以你應該定義一個拷貝構造函數。請注意,規則還告訴你定義一個複製賦值運算符,在這種情況下不需要。

+0

很好的答案,謝謝。 – SingerOfTheFall 2012-08-01 12:17:59

3

不,你不能。還可以有其他構造函數(至少是複製構造函數)。你不會數它們。

你也不能指望static變量很容易遭到破壞,因爲他們畢竟main退出

+0

我假設我們準確地增加了所有構造函數中的變量,並在所有析構函數中減少它。對不起,我應該把這個問題=( – SingerOfTheFall 2012-08-01 10:41:36

+0

MyClass析構函數也將需要虛擬 – DrYap 2012-08-01 10:41:42

+0

@SingerOfTheFall:什麼靜態實例? – Andrew 2012-08-01 10:42:57

1

誰說只有構造函數分配內存?如果某些非構造函數成員函數(靜態或非靜態)分配內存,並且析構函數沒有正確清理,則已經泄露了該內存。

所以,答案是沒有。您已經計算了通過標準構造函數創建的類實例。沒有更多,不少。

0

你假設MyClass(以及從它派生的任何東西)都被正確寫入。特別是,此泄漏不會被檢測到:

class BadClass : private MyClass 
{ 
    public: 
    BadClass() { int *x = new int(5); } 
} 

你的櫃檯做的是告訴你,你已經有一個破壞各施工,這意味着沒有人泄露任何「MyClass的」對象。

但這不是沒有內存泄漏。

相關問題