2014-02-24 155 views
1

當我用我自己的類的類型矢量內存,處理:使用std :: vector的

std::vector<CItem> m_vItems; 

在我的課,我初始化SFML類型,如質地和精靈:

class CItem 
{ 
    (...) 
    sf::Texture m_Texture; 
    sf::Sprite m_Sprite; 
    sf::IntRect* m_pRect; 
    (...) 
} 

我試圖通過反對我向量聲明爲其他類CLevel的成員,我正在做內部的類的方法是這樣的:

CItem *temp = new CItem(x, y, kind); 
m_vItems.push_back(*temp); 

正如你看到的,我不delete一個temp終場前delete,但在CLevel類的析構函數中我有一個簡單的一行:

std::vector<CItem>().swap(m_vItems); 

而且我對內存泄漏有點困惑。我的程序是否有這些或上面的解決問題的線,我的例子已被正確書寫?

+0

請插入析構函數的代碼 – 4pie0

+0

哪個析構函數? CItem還是CLevel? – Gucu112

回答

1
CItem *temp = new CItem(x, y, kind); 
m_vItems.push_back(*temp); // here a copy of *temp is pushed into vector 

你應該調用刪除某個刪除你臨時分配的:

delete temp; 

,以避免內存泄漏。任何撥打new的電話都必須與某個地方的delete有匹配的電話。這不影響被推入矢量中的臨時副本。只要存在矢量,它仍然存在。

最好是隻使用:

m_vItems.push_back(CItem(x, y, kind)); // implement this constructor correctly 
             // to avoid uninitialized variables 

始終當泄漏是關心你可以用工具分析您的程序:Valgrind的或Visual檢漏儀。

2

程序調用new而沒有匹配delete,它沒有將new的結果傳遞給其他一些可以爲你管理它的類。因此你的程序有內存泄漏。

你使用m_vItems.push_back(CItem(x, y, kind));而不是你給的兩行代碼有問題嗎?

+0

當我像這樣使用它時,方法的結束精靈的紋理得到不正確的寬度和高度的隨機值。 – Gucu112

+1

正確實施此構造函數以避免未初始化的變量 – 4pie0

0

如果您在Windows平臺上,則可以使用CRT庫來檢測特定代碼段中是否有任何泄漏。這個link解釋瞭如何在VS 2012中做到這一點,它也可用於早期版本。

0

假設你需要保留一個指針向量,而不是一個CItems向量,我會使用一個智能指針來管理對象的生命週期。一個shared_ptr易於使用:

shared_ptr<CItem*> temp(new CItem(x,y,z)); 
m_vItems.push_back(temp); 

當載體得好,CITEM將正確清理。當物品被傳遞時,它們也會被正確處理 - 沒有內存泄漏。

0

內存泄漏是空間分配在堆上(在你的情況下通過調用new)並且對該內存的引用丟失。換句話說,你無法通過調用delete來回收內存。如果使用swap將指針從一個向量移動到另一個向量,那麼在技術上這不是泄漏,因爲您仍然可以引用其他向量中的內存,並且仍然可以調用delete。

請記住最終會調用delete。根據使用情況,在某些情況下可能會很誘人,以便稍後讓系統清理,而不是永遠刪除內存,例如如果代碼是CGI。然而,當代碼用於最初並未預期的用例時,這可能會在稍後導致問題,例如,一個從長期運行的框架調用的單元測試。即使這樣做對於立即目標沒有任何影響,通常也值得花時間對刪除進行編碼,而不是將自己置於可能需要回圈並嘗試稍後修復的位置。