2011-09-10 11 views
7

Debugowałem mój program i zauważyłem, że mimo, że oznaczyłem prawie wszystkie z to jako komentarz i wszystko, co zrobiłem, to wcisnąć podwójne wartości do wektora Mam wyciek pamięci. Czytałem api w C++, ale nie mogłem nic znaleźć. Oto kod:nieczytelny przeciek pamięci z wektorem, C++, podczas wywoływania wyjścia

#include <vector> 
#include <cstdlib> 
#include <iostream> 
#include "RegMatrix.h" 
#include "Matrix.h" 

using namespace std; 

int main(void) 
{ 
    vector<double> v; 
    for (int i=0; i<9; i++) 
    { 
     v.push_back(i); 
    } 
    cout << endl; 

    exit(EXIT_SUCCESS); 
} 

I raport valgrind za:

==9299== HEAP SUMMARY: 
==9299==  in use at exit: 128 bytes in 1 blocks 
==9299== total heap usage: 5 allocs, 4 frees, 248 bytes allocated 
==9299== 
==9299== 128 bytes in 1 blocks are still reachable in loss record 1 of 1 
==9299== at 0x402569A: operator new(unsigned int) (vg_replace_malloc.c:255) 
==9299== by 0x804937D: __gnu_cxx::new_allocator<double>::allocate(unsigned int, void  const*) (in /home/yotamoo/workspace/ex3/main) 
==9299== by 0x804922F: std::_Vector_base<double, std::allocator<double>  >::_M_allocate(unsigned int) (in /home/yotamoo/workspace/ex3/main) 
==9299== by 0x8048E6C: std::vector<double, std::allocator<double>  >::_M_insert_aux(__gnu_cxx::__normal_iterator<double*, std::vector<double,  std::allocator<double> > >, double const&) (in /home/yotamoo/workspace/ex3/main) 
==9299== by 0x8048CA2: std::vector<double, std::allocator<double> >::push_back(double  const&) (in /home/yotamoo/workspace/ex3/main) 
==9299== by 0x8048B10: main (in /home/yotamoo/workspace/ex3/main) 
==9299== 
==9299== LEAK SUMMARY: 
==9299== definitely lost: 0 bytes in 0 blocks 
==9299== indirectly lost: 0 bytes in 0 blocks 
==9299==  possibly lost: 0 bytes in 0 blocks 
==9299== still reachable: 128 bytes in 1 blocks 
==9299==   suppressed: 0 bytes in 0 blocks 

To jest dziwne. Jakieś pomysły? Dzięki

+2

Jest to spowodowane funkcją exit(). Jest to stary kod C i nie może poprawnie obsługiwać destruktorów C++. – tp1

+0

Czy to możliwe, że v jest niszczony po wywołaniu wyjścia? Co zrobić, jeśli umieścisz znak v w swoim zasięgu (na przykład w nawiasach)? – nulvinge

+0

@yotamoo: Nawet nie musisz tego robić. Po osiągnięciu końca 'main' jest to samo, co zwracanie zera z głównego. (Jest to jedyna funkcja zadeklarowana jako zwracająca "int", która faktycznie nie musi zwracać czegoś) –

Odpowiedz

18

exit() nie wywołać destruktorów bieżącego zakresu tym samym nie może być przeciek:

(§3.6.1/4) Wywołanie funkcji void exit(int); zadeklarowanej w <cstdlib> (18,3) kończy program bez pozostawiając bieżący blok, a tym samym nie niszcząc żadnych obiektów z automatycznym czasem przechowywania (12.4). Jeśli wyjście zostanie wywołane w celu zakończenia programu podczas niszczenia obiektu o statycznym czasie przechowywania, program ma niezdefiniowane zachowanie.

Użyj tego zamiast:

#include <vector> 
#include <iostream> 

int main(int argc, char *argv[]) { 
    std::vector<double> v; 

    for (int i=0; i<9; i++) { 
     v.push_back(i); 
    } 

    std::cout << endl; 
    return 0; 
} 
+4

Pokonałeś mnie, a ty usunąłeś śmieci "używając przestrzeni nazw". +1 i nuked moja własna odpowiedź. –

+1

@Billy ONeal: I naprawiłem 'int main (void)';) – orlp

+1

@noccracker: faktycznie 'int main (void)' (lub, w lepszym stylu C++, 'int main()') * jest * poprawne ' główny podpis. –

1

Próbowałaś oddanie cały kod z wyjątkiem exit w oddzielnym bloku {}?

2

Nie wierzę, że masz wyciek pamięci. Kiedy valgrind mówi, że pamięć jest nadal dostępna, nie mówi ci, że wyciekła, ale nie została zwolniona przed zakończeniem programu. W tym przypadku wektor desctructor nie został wywołany przed wyjściem. Spróbuj wrócić z głównego, a nie wywołując exit().

7

Wektor nigdy nie wychodzi poza zasięg wyjścia.

Wystarczy wyjąć exit() od głównego i zastąpienie go return 0;

0

Nie trzeba wywołać funkcję wyjścia będzie natychmiastowe wyjście z programu nie zadzwonił OS oczyścić połączenia.

Zawsze używaj funkcji return(), a nie exit().