Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: yeray_pg en 1 Noviembre 2014, 09:54 am



Título: Memory Leak en código
Publicado por: yeray_pg en 1 Noviembre 2014, 09:54 am
Hola, mi problema es que tengo un código en C++ y he pasado el Valgrind para si habia memory leaks y efectivamente hay, lo que no sé es encontrarlos. SI me pudierais hechar una manita os lo agredeceria.

http://pastebin.com/ajsuZjKq es el código del main
http://pastebin.com/TFWCt8ah es el código del source

A continuación os dejo el mensaje del Valgrind:

Citar
==2722== 252 (144 direct, 108 indirect) bytes in 9 blocks are definitely lost in loss record 2 of 2
==2722== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2722== by 0x4011C7: sub(vector*, vector*) (in /home/yeray/Escritorio/164324_164376/p1)
==2722== by 0x40155E: distance(vector*, vector*) (in /home/yeray/Escritorio/164324_164376/p1)
==2722== by 0x401BCB: determinar_operacion(char*, vector**) (in /home/yeray/Escritorio/164324_164376/p1)
==2722== by 0x401DB0: main (in /home/yeray/Escritorio/164324_164376/p1)

Muchas gracias :)


Título: Re: Memory Leak en código
Publicado por: do-while en 1 Noviembre 2014, 11:46 am
¡Buenas!

La verdad es que bucear en un código ajeno es una locura.

Veo cosas raras como esta:

Código
  1. vector* create_vector( int n, float* data ) {
  2.        vector* v;
  3.        v = (vector*) malloc(sizeof( vector )); //creamos un puntero a una instancia del struct        
  4.        v->data = data;                                        
  5.        v->dim = n;                                     //inicializamos dim de v, numero de posiciones
  6.        return v;                                       //devolvemos v
  7. }
  8.  
  9. //...
  10. void destroy_vector( vector* v ) {
  11.        free( v->data );
  12.        free( v );              //desalojamos la memoria reservada
  13.  
  14. }
  15.  

A los datos les estás asignando un vector ajeno a la estructura, pero luego intentas liberar la memoria dentro de la propia estructura. La verdad es que no es coherente. Si el vector de datos es un vector exterior a la estructura, libera su memoria fuera de la estructura, o lo que me parece más lógico, crea dentro de la estructura de datos la memoria suficiente para almacenar los datos del vector que pasas en el "constructor" y luego copias su contenido en la memoria que acabas de reservar. Así tienes localizada cualquier asignación dinámica de memoria dentro de la propia estructura de datos y todo está más claro.

La cosa quedaría algo así:
Código
  1. vector* create_vector( int n, float* data ) {
  2.        vector* v;
  3.        v = (vector*) malloc(sizeof( vector )); //creamos un puntero a una instancia del struct
  4.        v->data = (float*) malloc(n * sizeof(float));
  5.        memcpy(v->data, data, n * sizeof(float));
  6.        v->dim = n;                                     //inicializamos dim de v, numero de posiciones
  7.        return v;                                       //devolvemos v
  8. }
  9.  

Luego, si el parámetro data que recibe esta función ha sido creado utilizando memoria dinámica, la liberas cuando esa variable no te haga mas falta o antes de que salga de su ámbito.

Si ordenas bien las ideas y el código te ahorraras bastantes quebraderos de cabeza. Revisa bien el código viendo donde asignas memoria y comprobando que liberas toda la que asignas.

¡Saludos!

PD: Te dejo un código un poco más claro para una de las funciones:
Código
  1. int contarcomas(char* cadena){
  2.        int j = 1;                            //inicializando en 1 nos ahorramos contar el primer carácter que es un [
  3.        int c = 1;                            // numero de comas                                  
  4.        while(cadena[j] != ']'){              //contar comas
  5.                if(cadena[j++] == ','){ //Siempre hay que incrementar j. Lo hacemos directamente aquí.
  6.                        c++;
  7.                }
  8.        }
  9.        return c;
  10. }
  11.  

¡Saludos!