2013-04-15 13 views
8

Sono abbastanza nuovo nella gestione della memoria C++ perché diversamente da C, ci sono più ostacoli per liberare tutta la memoria.Come eliminare veramente i vettori

Sto cercando di eliminare con successo un puntatore a vettore di qualsiasi tipo (cioè vettore * dati)

/** 
* 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; 
} 

Tuttavia, ottengo una perdita di memoria dopo l'utilizzo di valgrind

==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 

Come posso essere in grado di sbarazzarsi di tutte le tracce di perdite di memoria con il puntatore al vettore (ad esempio in fase di runtime)?

+4

'vettore * test_vect = ...' sfida lo scopo stesso per cui vettore esiste in primo luogo. – Nawaz

+1

Perché stai usando i puntatori con i vettori? – Rapptz

+1

"perché a differenza di C, ci sono più ostacoli per liberare tutta la memoria." Wat. – GManNickG

risposta

22

Per i principianti, non credo ci sia una perdita. Hai letto correttamente il Leak Summary avete inviato per il programma ?:

==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 

Hai perso 0 byte 0 blocchi. valgrind non riesce a trovare alcuna perdita definita, indiretta o possibile. Il tuo programma va bene.

Per inciso: Tu ... davvero non dovrebbe essere utilizzando new o delete in questa situazione con quel vettore. C++, esattamente come C, ha cose che entrano e escono dall'ambito dello stack se le dichiari come variabili regolari. Il codice seguente ottiene esattamente quello che hai fatto nella tua domanda, senza l'uso di new e delete:

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

Lo stack pulirà se stesso magicamente, perché std :: vector ha un distruttore che pulisce le sue risorse quando si va fuori dal campo di applicazione. Non è necessario renderlo dinamico e metterlo nell'area heap/free-store della memoria del programma, quando lo stack lo farà bene.

Inoltre, sembra che tu venga da C, quindi mi prenderò il tempo di dire: Benvenuto in C++. : D

+2

<3 @Rapptz per avermi fatto sapere come effettivamente leggere Valgrind. : D –

+1

Sebbene il tuo suggerimento funzioni per programmi piccoli e semplici, cosa dovrei fare se dovessi effettivamente creare una memoria allocata dinamicamente per un vettore? Il vettore che dura oltre una chiamata di funzione. – JBRPG

+0

@JBRPG Passa il tuo vettore come valore di ritorno (che è veloce perché C++ ora ha 'std :: move' e amici) oppure assegni il vettore dinamicamente e tieni traccia di te stesso. Puoi anche fare 'std :: unique_ptr >' e questo avrà la stessa semantica di un puntatore a un std :: vector, ma con cancellazione automatica dopo aver passato un nuovo vettore. Puoi anche passare le cose per riferimento nelle funzioni del C++, operare su di esse, e il valore dopo che la funzione esiste sarà modificato direttamente. È un bel momento per il C++. : D –

6

Penso che questa possa essere la risposta. Per quanto riguarda il C++, non ci sono perdite qui.

3

L'intero scopo di tali classi contenitore è eseguire la gestione della memoria per l'utente, l'allocazione, la riallocazione e la deallocazione. Metti il ​​contenitore nello stack, mantiene internamente i suoi contenuti allocati dinamicamente e, quando l'istanza del contenitore viene cancellata, elimina automaticamente i dati allocati dinamicamente.

L'istanziazione dinamica del contenitore stesso sconfigge lo scopo ed è quasi sempre del tutto inutile.

E sì, nel tuo caso, il vettore è davvero cancellato.

+0

Devo essere d'accordo con te perché, come ho cercato tra le altre domande, la maggior parte dei post ha confermato che il vettore è un wrapper di classe di memoria dinamico, che mi esonera dal dover inserire e cancellare manualmente il nuovo – JBRPG

+2

Non è solo vettoriale, ci sono numerose classi contenitore nella libreria standard C++ e ancora di più in librerie come Qt o boost. – dtech

-3

penso che è necessario chiamare

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

prima di eliminarlo

+3

No. Questo non ha niente a che fare con questo. –

Problemi correlati