2012-05-06 153 views
0

我創建使用mapPixel方式的概念的圖格(點的2D離散數),一類:內存泄漏(Valgrind的)

class MapPixel 
{ 
    friend class Map; 
protected: 
    int x; 
    int y; 
    float height; 
    float vegetation; 

    std::vector<const MapPixel*> neib; 
...methods declaration, default constructor/destructor 

其中neib是列表指向與其相鄰的其他MapPixels的指針。

我使用的方法

void MapPixel::addNeib(const MapPixel* neib_) 
{ 
    neib.push_back(neib_); 
} 

的指針添加到neiber像素構建的曲線圖(因爲邊界具有比中心像素少neibs,該列表尺寸依賴)。

我的做法是有一類地圖使用

pixels = new MapPixel*[width]; 
for (int i = 0; i < width; i++) 
    pixels[i] = new MapPixel[height]; 

我使用的方法MapPixel :: ADDNODE()在構造函數中地圖成員

MapPixel **pixels; 

::地圖()建立網絡(例如)

pixels[i][j].addNeib(&pixels[i][j+1]); 

並在Map ::〜Map()中我按照相反的順序刪除MapPixel(不刪除neibs避免雙重免費):

for (int i = 0; i < width; i++) 
    delete pixels[i]; 
delete pixels; 

Valgrind的說,有幾個大的內存泄漏這樣的:

2,509,088 bytes in 39,205 blocks are possibly lost in loss record 4,071 of 4,071 
    in MapPixel::addNeib(MapPixel const*) in Source/mappixel.cpp:52 
    1: malloc in vg_replace_malloc.c:266 
    2: operator new(unsigned long) in /usr/lib/libstdc++.6.0.9.dylib 
    3: __gnu_cxx::new_allocator&lt;MapPixel const*&gt;::allocate(unsigned long, void const*) in ... 
    4: std::_Vector_base&lt;MapPixel const*, std::allocator&lt;MapPixel const*&gt; &gt;::_M_allocate(unsigned long) in stl_vector.h:131 
    5: std::vector&lt;MapPixel const*, std::allocator&lt;MapPixel const*&gt; &gt;::_M_insert_aux(__gnu_cxx::__normal_iterator&lt;MapPixel const**, std::vector&lt;MapPixel const*, std::allocator&lt;MapPixel const*&gt; &gt; &gt;, MapPixel const* const&amp;) in vector.tcc:271 
    6: std::vector&lt;MapPixel const*, std::allocator&lt;MapPixel const*&gt; &gt;::push_back(MapPixel const* const&amp;) in stl_vector.h:608 
    7: MapPixel::addNeib(MapPixel const*) in mappixel.cpp:52 

所有與線52:

neib.push_back(neib_); 

有誰明白這一點?現在我失去了信心,如果我可以使用std :: vector來構建像素的neibs。

+0

在內存泄漏的可能出現的問題,你應該給我們倆如何頁頭(新),以及如何你的dealloc(刪除)......這裏部分缺失。例如。你以相反的順序刪除MaxPixel,好吧;但你是否是像素本身?我想答案是肯定的,而且給出的答案適用。儘管如此,讓全新的/刪除代碼來看看會更好! – ShinTakezou

+0

添加了刪除代碼。我說的不是因爲這個,因爲Valgrind並沒有抱怨新像素/新像素[我],所以我認爲這個問題不在那裏。 –

+1

應該不是'delete []'而是? – ShinTakezou

回答

1

請注意,valgrind表示「可能丟失」,而不是「肯定丟失」。差異很重要。具體含義見here

該錯誤是關於由vector<>實現代碼分配的塊,最有可能在vector增長時調整包含元素的內存塊大小。如果您正在分配MapPixel的實例並忘記釋放它們,您可能會得到這些內容,因爲包含vector的內容將無法釋放其內存,但這樣您也會收到有關自己的代碼的錯誤。

除非!當您釋放pixels陣列時,您使用的是delete[]還是delete?您正在使用delete。您需要使用delete[]。這確實是一個內存泄漏。您使用new[]分配的任何內容必須與delete[]一起釋放,否則只會爲第一個元素調用正確的析構函數(即使是由編譯器自動生成的析構函數)。

+0

+1有關像素的問題...剛完成評論關於缺乏細節... :) – ShinTakezou

+0

添加了代碼,我刪除像素。 –

0

正如已經提到的其他答案,內存泄漏很可能是由錯誤的delete運算符引起的。在構造函數中,你使用operator new[]創建數組的數組:

pixels = new MapPixel*[width]; 
for (int i = 0; i < width; i++) 
    pixels[i] = new MapPixel[height]; 

您需要使用相應的釋放爲陣列存儲陣列刪除operator delete[]

for (int i = 0; i < width; i++) 
    delete [] pixels[i]; 
delete [] pixels; 

不過,我建議你改爲使用嵌套的std::vector代替像素矩陣。這樣你可以免費獲得內存管理。

std::vector<std::vector<MapPixel> > pixels; 
// in constructor something like: 
pixels.resize(width, std::vector<MapPixel>(height)); 
// nothing to do in destructor 

對於你的鄰居,我不會用std :: vector的,而是一個普通的MapPixel *neib[8];(假設摩爾鄰居)或相當std::array<MapPixel*, 8> neib;。但我不知道你對這個項目有什麼其他的要求。

除了內存管理,使用STL容器爲您提供了其他好處,例如方便的成員函數,他們不腐爛的指針,只是僅舉幾例。

+0

「(因爲邊界比中心像素少neibs,這個列表取決於大小)」這就是爲什麼我沒有使用MapPixel * neib [8]。此外,分配只在開始時分配,std :: vector是常量訪問。關於答案,我會檢查它是否修復錯誤。 –

+1

@JCLeitão全息你獲得一些[局部性](http://en.wikipedia.org/wiki/Locality_of_reference),即用於該陣列的存儲器被直接集成在對象本身,而對於向量元素的存儲器位於別處在堆上。但考慮到這些事情可能更像是過早優化。 – moooeeeep

+0

可能丟失2,509,088個字節我認爲爲代碼添加熵尚不成熟... xD –