2016-08-02 13 views
-3

自分のスタックを実装するためにC++コードを書きました。しかし、私はそれを確認するためにvalgrindを使用するとき、それはメモリリークがあるかもしれないと言いました。私はとても長い間点検しましたが、それでもそれを見つけることはできません。このC++コードはどのようにしてメモリリークを起こすことができますか?

これはコードです:

#ifndef RE_STACK_H 
#define RE_STACK_H 

#include <cstdlib> 
#include "general.h" 

template <typename T> 
class Stack { 
private: 
    T* bottom; 
    T* top; 
    T* sentinel; 
    uint32 size; 
public: 
    Stack(uint32 size = 30); 
    ~Stack(); 
    void push(const T&); 
    T pop(); 
    void expand(); 
}; 

template <typename T> 
Stack<T>::Stack(uint32 size) :size(size){ 
    bottom = top = static_cast<T*>(malloc(size * sizeof(T))); 
    sentinel = bottom + size * sizeof(T); 
} 

template <typename T> 
Stack<T>::~Stack() { 
    while (top-- != bottom){ 
     top->~T(); 
    } 
    free(bottom); 
} 

template <typename T> 
void Stack<T>::push(const T& item){ 
    if(top == sentinel){ 
     expand(); 
    } 
    new(top++)T(item); 
} 

template <typename T> 
T Stack<T>::pop() { 
    if(bottom == top){ 
     return 0; 
    } 
    T re = *--top; 
    top->~T(); 
    return re; 
} 

template <typename T> 
void Stack<T>::expand() { 
    size *= 2; 
    uint32 temp = top - bottom; 
    bottom = static_cast<T*>(realloc(bottom, size * sizeof(T))); 
    top = bottom + temp; 
    sentinel = bottom + size * sizeof(T); 
} 
#endif //RE_STACK_H 




#include <iostream> 
#include "NTL/Stack.h" 

int main() { 
    return 0; 
} 

これはvalgrindからのエラー情報です:

==33519== HEAP SUMMARY: 
==33519==  in use at exit: 22,216 bytes in 190 blocks 
==33519== total heap usage: 256 allocs, 66 frees, 27,992 bytes allocated 
==33519== 
==33519== 2,064 bytes in 1 blocks are possibly lost in loss record 58 of 63 
==33519== at 0x10000817C: malloc_zone_malloc (in /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so) 
==33519== by 0x1005E1EFD: _objc_copyClassNamesForImage (in /usr/lib/libobjc.A.dylib) 
==33519== by 0x1005D5182: protocols() (in /usr/lib/libobjc.A.dylib) 
==33519== by 0x1005D5093: readClass(objc_class*, bool, bool) (in /usr/lib/libobjc.A.dylib) 
==33519== by 0x1005D2C13: gc_init (in /usr/lib/libobjc.A.dylib) 
==33519== by 0x1005DA24E: objc_initializeClassPair_internal(objc_class*, char const*, objc_class*, objc_class*) (in /usr/lib/libobjc.A.dylib) 
==33519== by 0x1005E7132: layout_string_create (in /usr/lib/libobjc.A.dylib) 
==33519== by 0x1005D583C: realizeClass(objc_class*) (in /usr/lib/libobjc.A.dylib) 
==33519== by 0x1005D5300: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib) 
==33519== by 0x1005D52E9: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib) 
==33519== by 0x1005D52E9: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib) 
==33519== by 0x1005D52E9: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib) 
==33519== 
==33519== LEAK SUMMARY: 
==33519== definitely lost: 0 bytes in 0 blocks 
==33519== indirectly lost: 0 bytes in 0 blocks 
==33519==  possibly lost: 2,064 bytes in 1 blocks 
==33519== still reachable: 0 bytes in 0 blocks 
==33519==   suppressed: 20,152 bytes in 189 blocks 
==33519== 
==33519== For counts of detected and suppressed errors, rerun with: -v 
==33519== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 18 from 18) 

私はいくつかのコメントを見てきた、と私は説明したい:

  1. ではなくmalloc()free()を使用しますとdelete、私はメモリ割り当てとクラス構築のプロセスを分けたいので、私のデストラクタで見ることができます。そして、私はいつもpop()アイテムを、私はクラスのデストラクタを使用してそれが適切に破壊されていることを確認しますが、私は後で使用するかもしれないので、メモリを解放しませんでした。ヨアヒムPileborgへ

  2. おかげで、sentinel = bottom + size * sizeof(T);sentinel = bottom + size;に変更する必要がありますが、これはvalgrindは、1つのブロック内2064バイトは、おそらく損失レコード58 63

  3. の中で失われていると言う理由私が知っているではありません実際にはコードを完成させていないので、コピーコンストラクタを作成して後で演算子を割り当てようとしています。コードが大きくないときにコードをテストしたいだけです。

  4. ご存知のとおり、ご使用の際にはごみのコードはごみとは言わないでください。malloc();あなたはSTLのソースコードを見れば、あなたはアロケータは

+2

Valgrindの出力では、コードが参照されていないように見えることに注意してください。つまり、メモリリークがないということです。 「リーク」は、プログラムの生存期間中に生きることになっているメモリを動的に割り当てる初期化コードから、間違いの可能性が高いと考えられます。 –

+0

このコードには多くの問題があります。まず、C++コードで 'malloc'を使わないで、デストラクタ('〜T() ')を手で呼び出さないでください。私はメモリ管理に関するチュートリアル、特に 'new/delete'についてコンサルタントすることをお勧めします。 – hfhc2

+0

デストラクタの呼び出しはオブジェクトを破壊しません。デストラクタは他のどのような関数でもあります。(mallocを使用する場合は 'free'を使用して)オブジェクトの割り当てを解除し、デストラクタを呼び出す必要があります –

答えて

0

をどのように働くかの方法は、最後に私はvalgrindので、それはだと思うことがわかります。私は、とにかく...でも私は、コードをたどると同じくらい簡単で書く理由は、私はエラーを得たの間違いを見つけるために私を助けた人々への感謝を

int main(int argc, char* argv[]){ 
    return 0; 
} 

を知らない:

  1. sentinelはサイズを追加するだけです。
  2. reallocデストラクタを呼び出す手助けはできません。
関連する問題