2013-04-15 17 views
8

Ich bin ziemlich neu in C++ Speicherverwaltung, weil im Gegensatz zu C, gibt es mehr Hürden, um den gesamten Speicher zu befreien.Wie lösche ich wirklich Vektoren

Ich versuche

einen Zeiger auf Vektor von jeder Art (dh Vektor * data)
/** 
* We test the program in accessing vectors 
* with dynamic storage 
**/ 
#include <iostream> 
#include <vector> // you must include this to use vectors 

using namespace std; 

int main (void){ 
    // Now let's test the program with new and delete 
    // for no memory leaks with vectors (type safe) 
    // however, just calling delete is not enough to free all memory 
    // at runtime 
    vector <int> * test_vect = new vector <int> (10,5); 

    // Print out its size 
    cout << "The size of the vector is " << test_vect->size() 
     << " elements" << endl; 

    // run through vector and display each element within boundary 
    for (long i = 0; i < (long)test_vect->size(); ++i){ 
     cout << "Element " << i << ": " << test_vect->at(i) << endl; 
    } 

    delete test_vect; 
    return EXIT_SUCCESS; 
} 

jedoch erfolgreich zu löschen, ich einen Speicherverlust erhalten, nachdem valgrind mit

==2301== HEAP SUMMARY: 
==2301==  in use at exit: 4,184 bytes in 2 blocks 
==2301== total heap usage: 4 allocs, 2 frees, 4,248 bytes allocated 
==2301== 
==2301== LEAK SUMMARY: 
==2301== definitely lost: 0 bytes in 0 blocks 
==2301== indirectly lost: 0 bytes in 0 blocks 
==2301==  possibly lost: 0 bytes in 0 blocks 
==2301== still reachable: 4,096 bytes in 1 blocks 
==2301==   suppressed: 88 bytes in 1 blocks 

Wie kann ich in der Lage sein, alle Spuren von Speicherlecks mit Zeiger auf Vektor (dh zur Laufzeit) loszuwerden?

+4

'Vektor * test_vect = ...' trotzt den eigentlichen Zweck aufrufen müssen, warum Vektor in erster Linie vorhanden ist. – Nawaz

+1

Warum verwenden Sie Zeiger mit Vektoren ..? – Rapptz

+1

"denn im Gegensatz zu C gibt es mehr Hürden, um alle Speicher zu befreien." Wat. – GManNickG

Antwort

22

Für den Anfang glaube ich nicht, dass es ein Leck gibt. Haben Sie richtig lesen die Leak Summary Sie für das Programm geschrieben ?:

==2301== LEAK SUMMARY: 
==2301== definitely lost: 0 bytes in 0 blocks 
==2301== indirectly lost: 0 bytes in 0 blocks 
==2301==  possibly lost: 0 bytes in 0 blocks 
==2301== still reachable: 4,096 bytes in 1 blocks 
==2301==   suppressed: 88 bytes in 1 blocks 

Sie 0 Byte 0 Blöcke verloren haben. valgrind kann keine eindeutigen, indirekten oder möglichen Lecks finden. Dein Programm ist in Ordnung.

Als beiseite: Sie ... sollte wirklich nicht mit diesem Vektor in dieser Situation mit new oder delete sein. C++, genau wie C, hat Dinge, die in den Stapel gelangen und außerhalb des Bereichs liegen, wenn Sie sie als reguläre Variablen deklarieren. Der folgende Code erzielt genau das, was Sie in Ihrer Frage haben, ohne die Verwendung von neuen und löschen:

int main (void){ 
    // Now let's test the program with new and delete 
    // for no memory leaks with vectors (type safe) 
    // however, just calling delete is not enough to free all memory 
    // at runtime (ThePhD: it is, actually!) 
    vector <int> test_vect(10,5); 

    // Print out its size 
    cout << "The size of the vector is " << test_vect.size() 
     << " elements" << endl; 

    // run through vector and display each element within boundary 
    for (long i = 0; i < (long)test_vect.size(); ++i){ 
     cout << "Element " << i << ": " << test_vect.at(i) << endl; 
    } 

    // (ThePhD: Look ma, no deletions!) 
    return EXIT_SUCCESS; 
} 

Der Stapel wird sich auf magische Weise aufzuräumen, weil std :: vector ein destructor hat, das seine Ressourcen bereinigt, wenn es geht aus dem Rahmen. Sie müssen es nicht dynamisch machen und es in den Heap/Free-Speicherbereich des Programmspeichers legen, wenn der Stack es gut macht.

Auch klingt es wie du kommst von C, also nehme ich mir die Zeit zu sagen: Willkommen in C++. : D

+2

<3 @Rapptz, um mich wissen zu lassen, wie man Valgrind liest. : D –

+1

Obwohl Ihr Vorschlag für kleine und einfache Programme funktioniert, Was würde ich tun, wenn ich tatsächlich einen dynamisch zugewiesenen Speicher für einen Vektor erstellen müsste? Der Vektor, der über einen Funktionsaufruf hinausgeht. – JBRPG

+0

@JBRPG Sie übergeben Ihren Vektor als Rückgabewert (was schnell ist, weil C++ nun 'std :: move' und friends hat) oder Sie ordnen den Vektor dynamisch zu und behalten ihn selbst. Sie können auch 'std :: unique_ptr >' und dies wird die gleiche Semantik wie ein Zeiger auf einen std :: Vektor haben, aber mit automatischer Löschung, nachdem Sie einen neuen Vektor übergeben haben. Sie können auch Dinge durch Referenz in C++ - Funktionen übergeben, auf ihnen arbeiten, und der Wert nach der Funktion wird direkt geändert. Es ist eine großartige Zeit für C++. : D –

6

Ich denke, das kann die Antwort sein. Was C++ betrifft, gibt es hier kein Leck.

3

Der ganze Zweck dieser Container-Klassen ist die Speicherverwaltung für Sie, Zuweisung, Neuzuweisung und Freigabe. Sie legen den Container auf den Stapel, er behält seinen Inhalt intern dynamisch zugewiesen, und wenn die Containerinstanz gelöscht wird, löscht er automatisch die dynamisch zugewiesenen Daten.

Dynamische Instanziierung des Containers selbst macht Sinn und ist fast immer sinnlos.

Und ja, in Ihrem Fall ist der Vektor wirklich gelöscht.

+0

Ich muss Ihnen zustimmen, weil, während ich andere Fragen durchforstete, die Mehrheit der Beiträge bestätigt, dass Vektor ein dynamischer Speicherklassenwrapper ist, der mich davon befreit, manuell neu zu setzen und – JBRPG

+2

zu löschen Es ist nicht nur Vektor, gibt es zahlreiche Container-Klassen in der C++ - Standard-Bibliothek und noch mehr in Bibliotheken wie Qt oder Boost. – dtech

-3

Ich glaube, Sie

if(test_vect != 0) 
{ 
    if(!test_vect->empty()) 
     test_vect->clear(); 
} 

vor dem Löschen es

+3

Nein. Das hat nichts damit zu tun. –