Foros del Web » Programación para mayores de 30 ;) » C/C++ »

[ERROR EN PROGRAMA]****glibc detected *** double free or corruption (!prev):

Estas en el tema de [ERROR EN PROGRAMA]****glibc detected *** double free or corruption (!prev): en el foro de C/C++ en Foros del Web. El problema es que cuando ejecutaba mi aplicación me saltaba el error mencionado en el título, acompañado de un mapeo de la memoria y de ...
  #1 (permalink)  
Antiguo 04/08/2009, 19:26
Avatar de jaao_death  
Fecha de Ingreso: abril-2009
Ubicación: Murcia/españa
Mensajes: 229
Antigüedad: 15 años
Puntos: 6
[ERROR EN PROGRAMA]****glibc detected *** double free or corruption (!prev):

El problema es que cuando ejecutaba mi aplicación me saltaba el error mencionado en el título, acompañado de un mapeo de la memoria y de los archivos que la utilizan:

*** glibc detected *** ./Client-1.11: double free or corruption (!prev): 0x08166d88 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0xb7d77604]
/lib/tls/i686/cmov/libc.so.6(cfree+0x96)[0xb7d795b6]
/usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb7f5a231]
/usr/lib/libstdc++.so.6(_ZdaPv+0x1d)[0xb7f5a28d]
./Client-1.11[0x804e665]
./Client-1.11[0x804adeb]
./Client-1.11[0x804b6bc]
./Client-1.11[0x804ec91]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe5)[0xb7d1e775]
./Client-1.11[0x8049ca1]
======= Memory map: ========
08048000-08052000 r-xp 00000000 08:11 1488061 /home/blackfox/BlackFoxLabel/Documents/C++Programation/TCPConnection/Client-1.11
08052000-08053000 r--p 00009000 08:11 1488061 /home/blackfox/BlackFoxLabel/Documents/C++Programation/TCPConnection/Client-1.11
08053000-08054000 rw-p 0000a000 08:11 1488061 /home/blackfox/BlackFoxLabel/Documents/C++Programation/TCPConnection/Client-1.11
08166000-08187000 rw-p 08166000 00:00 0 [heap]
b7c00000-b7c21000 rw-p b7c00000 00:00 0
b7c21000-b7d00000 ---p b7c21000 00:00 0
b7d07000-b7d08000 rw-p b7d07000 00:00 0
b7d08000-b7e64000 r-xp 00000000 08:01 523827 /lib/tls/i686/cmov/libc-2.9.so
b7e64000-b7e65000 ---p 0015c000 08:01 523827 /lib/tls/i686/cmov/libc-2.9.so
b7e65000-b7e67000 r--p 0015c000 08:01 523827 /lib/tls/i686/cmov/libc-2.9.so
b7e67000-b7e68000 rw-p 0015e000 08:01 523827 /lib/tls/i686/cmov/libc-2.9.so
b7e68000-b7e6b000 rw-p b7e68000 00:00 0
b7e6b000-b7e78000 r-xp 00000000 08:01 505061 /lib/libgcc_s.so.1
b7e78000-b7e79000 r--p 0000c000 08:01 505061 /lib/libgcc_s.so.1
b7e79000-b7e7a000 rw-p 0000d000 08:01 505061 /lib/libgcc_s.so.1
b7e7a000-b7e7b000 rw-p b7e7a000 00:00 0
b7e7b000-b7e9f000 r-xp 00000000 08:01 523846 /lib/tls/i686/cmov/libm-2.9.so
b7e9f000-b7ea0000 r--p 00023000 08:01 523846 /lib/tls/i686/cmov/libm-2.9.so
b7ea0000-b7ea1000 rw-p 00024000 08:01 523846 /lib/tls/i686/cmov/libm-2.9.so
b7ea1000-b7f85000 r-xp 00000000 08:01 464373 /usr/lib/libstdc++.so.6.0.10
b7f85000-b7f89000 r--p 000e3000 08:01 464373 /usr/lib/libstdc++.so.6.0.10
b7f89000-b7f8a000 rw-p 000e7000 08:01 464373 /usr/lib/libstdc++.so.6.0.10
b7f8a000-b7f90000 rw-p b7f8a000 00:00 0
b7f96000-b7fa0000 r-xp 00000000 08:01 523895 /lib/tls/i686/cmov/libnss_files-2.9.so
b7fa0000-b7fa1000 r--p 00009000 08:01 523895 /lib/tls/i686/cmov/libnss_files-2.9.so
b7fa1000-b7fa2000 rw-p 0000a000 08:01 523895 /lib/tls/i686/cmov/libnss_files-2.9.so
b7fa2000-b7fa6000 rw-p b7fa2000 00:00 0
b7fa6000-b7fa7000 r-xp b7fa6000 00:00 0 [vdso]
b7fa7000-b7fc3000 r-xp 00000000 08:01 506251 /lib/ld-2.9.so
b7fc3000-b7fc4000 r--p 0001b000 08:01 506251 /lib/ld-2.9.so
b7fc4000-b7fc5000 rw-p 0001c000 08:01 506251 /lib/ld-2.9.so
bfeaf000-bfec4000 rw-p bffeb000 00:00 0 [stack]
Aborted


Es muy curioso, después de una exhaustiva búsqueda logré dar con el error, era justo en el momento en que liberaba la memoria de un puntero a char, el cuál correspondía con un buffer para la el envío de data a través de un socket. el método que lo invocaba se encargaba de enviar toda la información, pues leí alguna vez que muy probablemente hayan casos en que la info no se mande en el primer intento y solo se mande una parcialidad de esta, por tanto englobe en un bucle, que evitaba esto, el send(). Para que vean el código y lo entiendan mejor:

Código:
 83 bool Socket::send(const string &data) const{
 82     if(!is_valid()) // se encarga de comprobar que el socket no tenga problemas.
 83     return false;
 84
 85     char *buf = new char[data.size()];
 86     strcpy(buf, data.c_str());
 87     int status = 0, total = 0;
 88     int bytesleft = data.size();
 89 
 90     while(total < data.size()){
 91 
 92         status = ::send(m_sock, buf+total, bytesleft, 0);
 93 
 94         if(status == -1){
 95                 delete[] buf;//probablemente saltaría aquí también
 96             return false;
 97         } 
 98         total += status;
 99         bytesleft -= status;
100     }
101     delete[] buf; // aquí es donde salta el error y probablemente si la condición anterior fuera cierta, saltaría allí.
102     return (status >= 0);
103 }
Este error es algo que desconozco completamente, aclaro que soy novato en C/C++, pero sé lo suficiente como para creer que no debería saltar ningún error, la verdad es que me sentí indignado al descubrir que la única solución dentro de mis posibilidades era olvidarme de la memoria dinámica, y creo que es necesario practicar y ver donde se podría aplicar, "Para futuros programas", la solución final es la siguiente:


Código:
78 bool Socket::send(const string &data) const{
 79 
 80     if(!is_valid())
 81         return false;
 82 
 83     char buf[data.size()];
 84     strcpy(buf, data.c_str());
 85     char *p = buf;
 86 
 87     int status = 0, total = 0;
 88     int bytesleft = data.size();
 89 
 90     while(total < data.size()){
 91 
 92         status = ::send(m_sock, p+total, bytesleft, 0);
 93 
 94         if(status == -1){
 95             return false;
 96         }
 97 
 98         total += status;
 99         bytesleft -= status;
100     }
101 
102     return (status >= 0);
103 }

Por ahora funciona, pero me gustaría saber a razón de qué me saltaba dicho error, cómo pude haberlo corregido, y qué he de tener en cuenta para la próxima vez que intente manipular memoria dinámica.
__________________
Mucha seguridad nunca es suficiente.... Por una red segura
El señor ilustre obscurece nuestras mentes
Usas Linux? http://www.dudalibre.com/gnulinuxcounter
  #2 (permalink)  
Antiguo 05/08/2009, 02:09
Avatar de Eternal Idol  
Fecha de Ingreso: mayo-2004
Ubicación: Lucentum
Mensajes: 6.192
Antigüedad: 20 años
Puntos: 74
Respuesta: [ERROR EN PROGRAMA]****glibc detected *** double free or corruption (!prev

El problema es muy simple, no estas reservando espacio suficiente y por lo tanto estas corrompiendo la memoria. El metodo size devuelve el numero de CARACTERES de la cadena y esto no incluye el 0 terminador. Por ejemplo si la cadena era "HOLA" size devuelve 4, es lo que reservas con new, y despues llamas a strcpy que va a copiar "HOLA" y el 0 terminador de cadena.

En cualquier caso me parece que estas perdiendo el tiempo con memoria dinamica cuando la solucion mas simple y logica no es crear una copia del string sino usar un casting con el metodo que ya usas (c_str) para obtener su contenido.

Código:
status = send(m_sock,  data.c_str() + total, bytesleft, 0);
__________________
¡Peron cumple, Evita dignifica! VIVA PERON CARAJO
  #3 (permalink)  
Antiguo 05/08/2009, 12:14
Avatar de jaao_death  
Fecha de Ingreso: abril-2009
Ubicación: Murcia/españa
Mensajes: 229
Antigüedad: 15 años
Puntos: 6
Respuesta: [ERROR EN PROGRAMA]****glibc detected *** double free or corruption (!prev

jeje, ya ves, a veces uno está pensando en pajaritos y se complica la vida....

grax...
__________________
Mucha seguridad nunca es suficiente.... Por una red segura
El señor ilustre obscurece nuestras mentes
Usas Linux? http://www.dudalibre.com/gnulinuxcounter
  #4 (permalink)  
Antiguo 05/08/2009, 12:55
Avatar de Eternal Idol  
Fecha de Ingreso: mayo-2004
Ubicación: Lucentum
Mensajes: 6.192
Antigüedad: 20 años
Puntos: 74
Respuesta: [ERROR EN PROGRAMA]****glibc detected *** double free or corruption (!prev

De nadas
__________________
¡Peron cumple, Evita dignifica! VIVA PERON CARAJO
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 10:06.