2012-05-06 8 views
0

IはmapPixelの概念を用いて、マップグリッド(点の2次元離散的な数)を作成していクラス:neibはリストであるメモリリーク(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 

それに隣接する他のMapPixelsへのポインタ。

Iグラフを構築するneiberピクセルへのポインタを追加する方法を

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

を使用している(境界が中心画素未満neibsを有しているので、このリストは、サイズに依存します)。

マイ手続きコンストラクタ地図で

MapPixel **pixels; 

メンバーを持つクラスマップを持つことである::マップ()

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

を使用して、私は方法のMapPixel ::てaddNodeを(使用)へ

となります。Map ::〜Map()では逆の順序でMapPixelを削除します(削除する必要はありません)。 neibs二重解放を避けるために):

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に関連するすべて:

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

Valgrindのは、このようないくつかの大きなメモリリークがあると言う

neib.push_back(neib_); 

誰もがこれを理解しています?今私はstd :: vectorを使ってピクセルのneibを構築できるかどうか確信がなくなりました。

+0

メモリリークの可能性のある問題では、alloc(new)とdealloc(delete)の両方の方法を教えてください。例えば。 MaxPixelを逆の順序で削除します。あなたはピクセルそのものですか?私は答えがイエスであり、与えられた答えが当てはまると思います。しかし、見るために完全な新しい/削除コードを持つ方が良いでしょう! – ShinTakezou

+0

に削除コードが追加されました。私はValgrindが新しいピクセル/新しいピクセル[i]に不平を言うことはないので、それが原因ではないと言います。なぜそれが問題ではないと仮定したのでしょうか。 –

+1

は代わりに 'delete []'にするべきではありませんか? – ShinTakezou

答えて

1

注valgrindのではない "は間違いが失われた"、 "はおそらくが失われた" と述べています。違いは重要です。正確な意味については、hereを参照してください。

このエラーは、vector<>実装コードによって割り当てられたブロックに関するもので、vectorのサイズが大きくなるにつれて、要素を含むメモリブロックのサイズを変更する可能性が高くなります。 MapPixelのインスタンスを割り当てて解放するのを忘れると、vectorが含まれていてメモリを解放することはできませんが、自分自身のコードについてもエラーが発生するため、これらを取得する可能性があります。

pixelsアレイを解放するときは、delete[]またはdeleteを使用していますか?

更新:deleteを使用しています。 delete[]を使用する必要があります。これは確かにメモリリークです。 new[]で割り当てるものはdelete[]で解放する必要があります。そうしないと、適切なデストラクタ(コンパイラによって自動的に生成されたものでも)は最初の要素に対してのみ呼び出されます。

+0

ピクセルについての質問+1 ...詳細の不足についてコメントしました。:) – ShinTakezou

+0

ピクセルを削除するコードを追加しました。 –

0

すでに述べたもう1つの答えとして、メモリリークは、おそらく間違った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 ::ベクトルが、平野MapPixel *neib[8];(ムーア近所を仮定した場合)か、むしろstd::array<MapPixel*, 8> neib;を使用していないだろう。しかし、私はあなたがこのアイテムにどんな他の必要条件を持っているかも知りません。

メモリ管理以外にも、STLコンテナを使用すると、他の利点も得られます。例えば、便利なメンバ関数など、ポインタには崩壊しません。

+0

"(境界が中心ピクセルよりもneibが少ないので、このリストはサイズに依存します)"だから私はMapPixel * neib [8]を使わなかったのです。また、割り当ては最初にのみ行われ、一度割り当てられるとstd :: vectorは常にアクセスされます。答えについては、私はそれがエラーを修正するかどうかを確認します。 –

+1

@JCLeitãonahあなたはいくつかの[地域](http://ja.wikipedia.org/wiki/Locality_of_reference)を取得します。つまり、配列のメモリはオブジェクト自体に直接組み込まれていますが、ベクトル要素のメモリは他の場所にありますヒープ上に。しかし、このようなことを検討するのはおそらく時期尚早最適化のようなものです。 – moooeeeep

+0

2,509,088バイトが失われていると思いますが、エントロピーをコードに追加するのは時期尚早です... xD –

関連する問題