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

Problema con destructores y delete

Estas en el tema de Problema con destructores y delete en el foro de C/C++ en Foros del Web. Me sale un mensaje de error por terminal cuando intento hacer un delete dentro de un destructor. El caso es que no indica codeblocks ningún ...
  #1 (permalink)  
Antiguo 21/10/2014, 15:02
 
Fecha de Ingreso: octubre-2014
Mensajes: 23
Antigüedad: 9 años, 6 meses
Puntos: 0
Problema con destructores y delete

Me sale un mensaje de error por terminal cuando intento hacer un delete dentro de un destructor. El caso es que no indica codeblocks ningún fallo de código.
Código C++:
Ver original
  1. class C
  2. {
  3.     int * elem;
  4.     public:
  5.     C(long n)
  6.     {
  7.         elem= new int [n];
  8.     }
  9.     ~C()
  10.     {
  11.         delete [] elem;
  12.     }
  13. };
  14.  
  15. int main()
  16. {
  17.     C a(5);
  18.     a.~C();
  19.  
  20.     return 0;
  21. }
Dejo el mensaje de error..
Código:
*** glibc detected *** ./ejemplo: double free or corruption (fasttop): 0x080f4008 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x75b12)[0xb7515b12]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdlPv+0x1f)[0xb76f351f]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdaPv+0x1b)[0xb76f357b]
./ejemplo[0x80484f0]
./ejemplo[0x80484af]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb74b94d3]
./ejemplo[0x80483e1]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:05 10888315   /home/alejandro/Escritorio/Programas C/Maths/ejemplo
08049000-0804a000 r--p 00000000 08:05 10888315   /home/alejandro/Escritorio/Programas C/Maths/ejemplo
0804a000-0804b000 rw-p 00001000 08:05 10888315   /home/alejandro/Escritorio/Programas C/Maths/ejemplo
080f4000-08115000 rw-p 00000000 00:00 0          [heap]
b7453000-b7455000 rw-p 00000000 00:00 0 
b7455000-b7471000 r-xp 00000000 08:05 6423436    /lib/i386-linux-gnu/libgcc_s.so.1
b7471000-b7472000 r--p 0001b000 08:05 6423436    /lib/i386-linux-gnu/libgcc_s.so.1
b7472000-b7473000 rw-p 0001c000 08:05 6423436    /lib/i386-linux-gnu/libgcc_s.so.1
b7473000-b749d000 r-xp 00000000 08:05 6432598    /lib/i386-linux-gnu/libm-2.15.so
b749d000-b749e000 r--p 00029000 08:05 6432598    /lib/i386-linux-gnu/libm-2.15.so
b749e000-b749f000 rw-p 0002a000 08:05 6432598    /lib/i386-linux-gnu/libm-2.15.so
b749f000-b74a0000 rw-p 00000000 00:00 0 
b74a0000-b7644000 r-xp 00000000 08:05 6432584    /lib/i386-linux-gnu/libc-2.15.so
b7644000-b7646000 r--p 001a4000 08:05 6432584    /lib/i386-linux-gnu/libc-2.15.so
b7646000-b7647000 rw-p 001a6000 08:05 6432584    /lib/i386-linux-gnu/libc-2.15.so
b7647000-b764a000 rw-p 00000000 00:00 0 
b764a000-b7722000 r-xp 00000000 08:05 1318061    /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7722000-b7723000 ---p 000d8000 08:05 1318061    /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7723000-b7727000 r--p 000d8000 08:05 1318061    /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7727000-b7728000 rw-p 000dc000 08:05 1318061    /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7728000-b772f000 rw-p 00000000 00:00 0 
b774d000-b7750000 rw-p 00000000 00:00 0 
b7750000-b7751000 r-xp 00000000 00:00 0          [vdso]
b7751000-b7771000 r-xp 00000000 08:05 6432601    /lib/i386-linux-gnu/ld-2.15.so
b7771000-b7772000 r--p 0001f000 08:05 6432601    /lib/i386-linux-gnu/ld-2.15.so
b7772000-b7773000 rw-p 00020000 08:05 6432601    /lib/i386-linux-gnu/ld-2.15.so
bfcdb000-bfcfc000 rw-p 00000000 00:00 0          [stack]
Gracias de antemano.
  #2 (permalink)  
Antiguo 21/10/2014, 22:42
lareto
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Problema con destructores y delete

El problema es que el destructor se está invocando dos veces, y entonces delete [] elem; se ejecuta dos veces también, y es ahí donde se produce:
Cita:
*** glibc detected *** ./ejemplo: double free or corruption (fasttop): 0x080f4008 ***
(Y lo dice con todas las letras: "double free")

Código:
int main()
{
    C a(5);
   //  a.~C();             // comenta esto
 
    return 0;
}  //  acá es donde se invoca al destructor de a
"a" es una variable local de main(), y cuando sale de ámbito (scope), se invoca su destructor.

Sólo en casos muy, pero muy, particulares se necesita invocar un destructor explícitamente.

Lareto :)
  #3 (permalink)  
Antiguo 22/10/2014, 09:00
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 6 meses
Puntos: 38
Respuesta: Problema con destructores y delete

Muy bien señalado por lareto.
El destructor es una función que se ejecuta automáticamente al cerrar el programa. No tienes por que llamarlo.
Pero si quieres liberar memoria te aconsejo que hagas una función freeMem() a la que puedas llamar cuando quieras y así puedes prescindir de usar el destructor. Pero no te olvides de liberar la memoria XD
Mire eso:
Código C++:
Ver original
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. class lol {
  5.     public:
  6.         lol(){ cout << "constructor llamado, se ha creado el objeto!" << endl; }
  7.         ~lol(){
  8.             cout << "Destructor llamado! Aqui se destruye automatico" << endl;
  9.             cin.ignore(); //Se va pausar para que puedas ver el mensaje antes de salir de main
  10.         }
  11.        
  12.     private:
  13.     //blabla bla bla!
  14. };
  15.  
  16. int main (){
  17.    
  18.     lol miLol;    //Crea el objeto
  19.    
  20.     cin.ignore(); // Pausa
  21.    
  22.     cout << "aqui debajo se va llamar automaticamente el destructor" << endl;
  23.     return 0;
  24. }

como buena practica de programación es asignar NULL al puntero después de liberar memoria, para que no haya problemas por una doble limpieza de memoria pues haz algo como:

Código C++:
Ver original
  1. ~C() {
  2.     if ( puntero != NULL ) {
  3.         delete [] puntero;
  4.         puntero = NULL; // ahora sabemos que apunta a NADA y podemos averiguar posteriormente.
  5.     }
  6. }

Con eso si ya habías llamado el destructor pues asigna NULL al puntero y cuando el destructor es llamado automáticamente al final va a ver que ya no apunta a nada y no va haber problemas XD

Te dejo la posible solución:
Código C++:
Ver original
  1. #include <iostream>
  2. using namespace std;
  3.  
  4.  
  5.  
  6. class C {
  7.         int * elem;
  8.     public:
  9.         C ( long n ) {
  10.             elem = new int [n];
  11.         }
  12.         ~C() {
  13.                 cout << "Destructor llamado"<<endl;
  14.             if ( elem != NULL ) {
  15.                 cout << "se ha liberado la memoria y elem apunta a NULL" <<endl;
  16.                 delete [] elem;
  17.                 elem = NULL;
  18.             }else{
  19.                 cout << "elem ya habia sido liberado previamente" << endl;
  20.             }
  21.         }
  22. };
  23.  
  24. int main() {
  25.     C a ( 5 );
  26.     a.~C();
  27.    
  28.     return 0;
  29. }


Última edición por vangodp; 22/10/2014 a las 09:13
  #4 (permalink)  
Antiguo 22/10/2014, 09:19
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Problema con destructores y delete

Cita:
Iniciado por vangodp Ver Mensaje
Con eso si ya habías llamado el destructor pues asigna NULL al puntero y cuando el destructor es llamado automáticamente al final va a ver que ya no apunta a nada y no va haber problemas XD
Precisamente creo que es positivo que el programa te falle si llamas dos veces al destructor de un mismo objeto... básicamente porque en el lapso que va de la primera destrucción a la segunda estás usando un objeto no válido sin saberlo que puede dar todo tipo de problemas... con el primer destructor la memoria ya ha sido liberada y puede ser utilizada por cualquier otro proceso.

Por otro lado... si en un momento dado haces una llamada a un objeto y ves que ha perdido su puntero porque ahora apunta a NULL también te puede dar pistas... nada impide poner un breakpoint en la posición de memoria ocupada por el puntero para que el depurador se pare cuando éste cambia.
  #5 (permalink)  
Antiguo 24/10/2014, 14:52
 
Fecha de Ingreso: octubre-2014
Mensajes: 23
Antigüedad: 9 años, 6 meses
Puntos: 0
Respuesta: Problema con destructores y delete

Muchas gracias, aunque lo que habia puesto era algo simplificado de mi programa donde crei que estaba el error. Sin embargo me tira otro distinto:
Código:
*** glibc detected *** ./example: free(): invalid pointer: 0x08ab0030 ***
Sospecho algo relacionado con this->.
this-> se debe usar sólo cuando sea necesario o se puede usar siempre que uno quiera¿?

Creo que he puesto this-> muy redundantes, no se si sera eso, probe a quitarlo en una funcion y ya me iba.
  #6 (permalink)  
Antiguo 24/10/2014, 17:07
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Problema con destructores y delete

"this" se puede usar a discrección... puedes tener la implementación de una clase plagada de "this" o sin uno solo y el código será igual de válido (obviamente si no hay colisión con los nombres de las variables).

Ese error tiene que ver con la liberación de recursos... qué código tienes para que te genere ese error??

Etiquetas: delete, int, programa
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 11:08.