2011-09-10 6 views
7

Estaba depurando mi programa y me he dado cuenta de que aunque he marcado casi todos como comentario y todo lo que hice fue insertar valores dobles en un vector , Tengo una pérdida de memoria. Leí la API en referencia a C++, pero no pude encontrar nada. Aquí está el código:fuga de memoria no clara con el vector, C++, al llamar a la salida

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

y el informe de valgrind:

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

Esto es raro. ¿Algunas ideas? gracias

+2

Es causado por la función exit(). Es un código C antiguo y no puede manejar correctamente los destructores de C++. – tp1

+0

¿Podría ser que v esté desestructurado después de llamar a la salida? ¿Qué sucede si coloca v en su propio ámbito (por ejemplo, con corchetes)? – nulvinge

+0

@yotamoo: Ni siquiera tienes que hacer eso. Cuando se alcanza el final de 'main', es lo mismo que devolver cero desde main. (Es la única función declarada como devolver un 'int' que en realidad no tiene que devolver algo) –

Respuesta

18

exit() no llamará a los destructores del ámbito actual por lo tanto no puede haber una fuga:

(§3.6.1/4) Llamar a la función declarada en void exit(int);<cstdlib> (18.3) termina el programa sin dejando el bloque actual y por lo tanto sin destruir ningún objeto con duración de almacenamiento automático (12.4). Si se llama a exit para finalizar un programa durante la destrucción de un objeto con duración de almacenamiento estático, el programa tiene un comportamiento indefinido.

Use este lugar:

#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

Me ganaste y eliminaste la basura 'using namespace'. +1 y destruyó mi propia respuesta. –

+1

@Billy ONeal: Y arreglé 'int main (void)';) – orlp

+1

@nightcracker: en realidad 'int main (void)' (o, en un mejor estilo C++, 'int main()') * es * a valid' firma principal –

1

¿Usted intentó poner todo el código, excepto exit en un bloque separado {}?

2

No creo que tenga una pérdida de memoria. Cuando Valgrind dice que la memoria aún es alcanzable, no te dice que se filtró, pero que no fue liberado antes de que el programa saliera. En este caso, el vector desctructor no se llamó antes de la salida. Intente regresar desde main en lugar de llamar a exit().

7

El vector nunca sale del alcance de la salida.

Basta con retirar la exit() del principal y sustituirla por una return 0;

0

Usted no tiene que llamar a la función de salida será la salida inmediata del programa no llamar al sistema operativo a limpiar las llamadas.

Utilice siempre la función de retorno() para salir().

Cuestiones relacionadas