Título: [C++][Consulta] Error inesperado con destructor Publicado por: class_OpenGL en 3 Febrero 2017, 04:28 am Hola, muy buenas. Estoy realizando un árbol binario en C++. Lo estoy encapsulando en una clase. Como cualquier árbol binario, este tiene un dato, un puntero a la izquierda y otro a la derecha. El problema es que al llamar al destructor (el cual lo elimina), el programa finaliza brúscamente. El constructor es el siguiente:
Código
Este es la función main: Código
Cuando uso el depurador, pongo un punto de ruptura en el destructor, y obtengo lo siguiente: Código: Breakpoint 1, ArbolBinario<int>::~ArbolBinario (this=0x28fddc, __in_chrg=<optimized out>) at main.cpp:84 Lo que no sé es: ¿por qué se llama 3 veces al constructor? En la última llamada, ¿por qué el puntero this vale 0 (supongo que por esto el programa crashea)? Muchas gracias Título: Re: [C++][Consulta] Error inesperado con destructor Publicado por: MAFUS en 3 Febrero 2017, 07:22 am A mi entender duplicas las cosas.
En el destructor vas a borrar las dos ramas por separado pero estas funciones terminan apoyándose en Eliminar, que de igual forma vuelve a borrar a la izquierda y a la derecha por sí misma. Tal vez debería ser al revés, que Eliminar estuviera a un nivel superior y fuera las que llamara a eliminar izquierda y derecha para borrar así el nodo completo. De igual forma, tal y como lo tienes, solo EliminarRamaIzda y EliminarRamaDcha se encargan de llevar a NULL el puntero pero Eliminar no lo hace. ¿Llega el programa a un punto en que Eliminar pasará sobre un puntero que ya ha sido borrado previamente? Título: Re: [C++][Consulta] Error inesperado con destructor Publicado por: class_OpenGL en 3 Febrero 2017, 08:51 am No entiendo muy bien eso de duplico. A ver, tengo el método Eliminar, que te elimina una rama del árbol. Este no comprueba que el árbol que le pases sea nulo (es una precondición que no será así, por así decirlo). Una vez que tengo ese método, creo otros dos que te eliminan la rama izquierda y la rama derecha, las cuales comprueban si la rama es válida (si esta no es nula). Una vez que tengo dos métodos que te eliminan dos ramas (sé que se podría haber resumido en una, pero me pareció útil para mis propósitos) tener métodos que te eliminen ramas independientes. El caso es que el constructor elimina el árbol formado por la rama izquierda y elimina el formado por la de la derecha:
Destructor: Elimina rama izquierda. Elimina rama derecha No entiendo dónde está el conflicto. ________________________________________________________ He probado, desde el main, hacer lo del constructor, lo he eliminado y así si que funciona. Nuevo main: Código
Por lo que alguna condición/requisito especial tiene que tener el destructor. _____________________________________________________________ He probado a poner cout << "Algo" << endl en el destructor y esto sale: Algo Algo Algo Algo Algo Algo Algo Algo Algo ¿Por qué se llama tantas veces? ______________________________________________________________ Soy nuevo en C++ (vengo de C), ¿delete Objeto llama al destructor del objeto? Título: Re: [C++][Consulta] Error inesperado con destructor Publicado por: MAFUS en 3 Febrero 2017, 14:24 pm Si pudieras pasar tu código entero para probar mejor.
La idea es: Código
Lo dicho, si tuviera el código completo del árbol podría probarlo, pero por ahora esa es mi idea. Puede tener una infinidad de bugs, código no probado. Título: Re: [C++][Consulta] Error inesperado con destructor Publicado por: ivancea96 en 3 Febrero 2017, 14:35 pm Código
Eliminar no establece las ramas a NULL. COn esta función recursiva, estás eliminando todas las ramas, pero de manera incorrecta: Primero, liberas la memoria de cada lado de la rama. Luego, llamas al destructor de la rama y la liberas. El destructor de la rama, ya llama a Eliminar. Solo que ahora, llama a Eliminar sobre unas ramas que no apuntan a nada válido. Título: Re: [C++][Consulta] Error inesperado con destructor Publicado por: class_OpenGL en 3 Febrero 2017, 18:19 pm Sii con el gdb (y mucho esfuerzo, por fin me entere del problema. Con C++ hay que tener un cuidado especial, tanto o mas que con C xD (supongo que sera cuestion de muucha practica, como siempre)
Muchas gracias por sus respuestas!! |