2016-08-02 12 views
-3

Ich schrieb etwas C++ Code, um meinen eigenen Stapel zu implementieren. Aber wenn ich valgrind verwende, um es zu überprüfen, sagte es, dass es Speicherverlust geben kann. Ich habe so lange nachgesehen, kann es aber immer noch nicht finden.Wie kann dieser Teil von C++ Code Speicherleck bekommen?

Dies ist der Code:

#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; 
} 

Dies ist die Fehlerinformationen von 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) 

ich einige Kommentare gesehen haben, und ich möchte erklären:

  1. Ich verwende malloc() und free() statt new und delete, weil ich den Prozess der Speicherzuweisung und Klassenkonstruktion trennen möchte, und Sie können in meinem Destruktor sehen, ich Speicher dort freigeben. Und jedes Mal, wenn ich einen Gegenstand verwende, benutze ich den Destruktor der Klasse, um sicherzustellen, dass er richtig zerstört ist, aber Ich habe den Speicher nicht freigegeben, da ich ihn später verwenden kann.

  2. Dank Joachim Pileborg, sentinel = bottom + size * sizeof(T); sollte sentinel = bottom + size; geändert werden, aber das ist nicht der Grund, warum valgrind sagt 2.064 Bytes in 1 Blöcke möglicherweise in Verlust-Rekord 58 von 63

  3. verloren weiß ich, ich Ich habe die 3/5-Regeln nicht befolgt, ich habe den Code nicht fertig gestellt und schreibe den Kopierkonstruktor und weise den Operator später zu, und ich möchte nur den Code testen, wenn er nicht groß ist.

  4. Bitte sagen Sie nicht, der Code ist Müll, wenn Sie nur einen Blick haben und bemerke, dass ich malloc(); wenn Sie jemals den Quellcode von STL sehen, werden Sie, dass die Art und Weise sehen, wie allocator

+2

Beachten Sie in der Valgrind-Ausgabe, dass keiner von Ihrem Code referenziert wird? Das bedeutet, dass Sie kein Speicherleck haben. Das "Leck" ist höchstwahrscheinlich ein falsches positives Ergebnis, von einem Initialisierungscode, der Speicher dynamisch zuweist, der für die Lebenszeit des Programms leben soll. –

+0

Es gibt viele Probleme mit diesem Code, für Anfänger: Verwenden Sie nicht "malloc" in C++ - Code, auch nicht nennen Destruktoren ('~ T()') von Hand. Ich würde Ihnen empfehlen, ein Tutorial zum Thema Speicherverwaltung zu verfassen, insbesondere zu 'new/delete' – hfhc2

+0

Der Aufruf von Destruktoren zerstört das Objekt nicht. Der Destruktor ist eine Funktion wie jede andere.Sie müssen die Zuweisung des Objekts aufheben (indem Sie "free" verwenden, wenn Sie malloc verwenden), das dann den Destruktor aufrufen wird –

Antwort

0

Schließlich funktioniert finde ich es, weil valgrind ist. Ich weiß nicht, warum, auch schreibe ich genauso einfach wie Codes folgen, bekam ich einen Fehler ...

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

Wie dem auch sei, dank den Menschen, die mir helfen, die Fehler herauszufinden:

  1. sentinel muss nur Größe hinzufügen ...
  2. realloc kann mir nicht helfen, Destruktor zu nennen.