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

Eliminar objeto con delete

Estas en el tema de Eliminar objeto con delete en el foro de C/C++ en Foros del Web. Hola . He tenido un problema que me está volviendo loco.He oído que los objetos creados con new deben ser eliminados con delete. Tengo una ...
  #1 (permalink)  
Antiguo 29/08/2012, 02:39
 
Fecha de Ingreso: julio-2011
Ubicación: Querétaro México
Mensajes: 34
Antigüedad: 11 años, 8 meses
Puntos: 0
Pregunta Eliminar objeto con delete

Hola .
He tenido un problema que me está volviendo loco.He oído que los objetos creados con new deben ser eliminados con delete.

Tengo una clase llamada Bot de la cual creo un objeto. En main llamo a un método de este objeto que se encarga de escribir un saludo en pantalla. Después lo elimino y para asegurarme de que ha sido eliminado vuelvo a llamar al método Saluda. Lo que no entiendo es: ¿ por qué se puede ejecutar el método Saluda si se supone que el objeto ya no existe?

Código.
Código:
#include <iostream>
using namespace std;

class Bot
{
	
	public:
	
	void Saluda();
    
};

void Bot :: Saluda()
{
	 	 cout<<"HOLA. "<<endl;
}


int main()
{
  
  Bot * bot;
  
  bot=new Bot();
   	
  bot->Saluda();  // llamamos metodo Saluda	
  
  delete bot;     // eliminamos el objeto
  
  bot->Saluda();  // llamada a Saluda de un objeto supuestamente eliminado
                           // se supone que debería salir error por tratar llamar a un metodo
                          // de un objeto que ya no existe.
  
}

La salida es:
Código:
HOLA. 
HOLA.
):, se supone que solo debe escribir HOLA una vez y sacar error en la segunda por tratar llamar un metodo de un objeto que supuestamente ya eliminé.

¿Qué sucede? , ¿ Cómo puedo solucionarlo?.
Saludos.
  #2 (permalink)  
Antiguo 29/08/2012, 08:08
 
Fecha de Ingreso: agosto-2012
Mensajes: 30
Antigüedad: 10 años, 7 meses
Puntos: 3
Respuesta: Eliminar objeto con delete

Hola Tortoiseius

Primero

en la clase de tu objeto Bot, no tienes declarado un destructor. Modifica tu clase para que quede asi:

Código C++:
Ver original
  1. class Bot
  2. {
  3.    
  4.     public:
  5.           void Saluda();
  6.                ~Bot();      //Declaracion del destructor
  7.    
  8. };

y luego, obviamente, declaras la funcion del destructor, asi

Código C++:
Ver original
  1. Bot::~Bot
  2. {
  3. }

Segundo

Cuando liberes el objeto, no debes hacerlo asi
Código C++:
Ver original
  1. delete bot;

sino asi

Código C++:
Ver original
  1. delete[] bot;

De esta manera, si que da error al ejecutar el codigo, con lo que solo se imprime una vez HOLA y luego salta un error de la aplicacion.


Espero que te sirva.
  #3 (permalink)  
Antiguo 29/08/2012, 11:18
 
Fecha de Ingreso: julio-2011
Ubicación: Querétaro México
Mensajes: 34
Antigüedad: 11 años, 8 meses
Puntos: 0
Respuesta: Eliminar objeto con delete

Oh muchas gracias amigo, ahora mismo lo pruebo a ver si todo funciona bien y lo comento.
  #4 (permalink)  
Antiguo 29/08/2012, 11:41
 
Fecha de Ingreso: julio-2011
Ubicación: Querétaro México
Mensajes: 34
Antigüedad: 11 años, 8 meses
Puntos: 0
Respuesta: Eliminar objeto con delete

Lucas_Max , he eliminado el objeto de la forma que mencionaste : creando un destructor y usando delete[] . y efectivamente obtengo un error. El problema es que el error aparece al tratar de eliminar el objeto y no al tratar de llamar una función del objeto que ya no existe.

Si en main quito los
Cita:
bot->Saluda();
de todas formas obtengo un error al eliminar el objeto
  #5 (permalink)  
Antiguo 29/08/2012, 14:23
 
Fecha de Ingreso: agosto-2012
Mensajes: 30
Antigüedad: 10 años, 7 meses
Puntos: 3
Respuesta: Eliminar objeto con delete

Hola Tortoiseius

Voy a mirar el codigo de nuevo y te aviso.
  #6 (permalink)  
Antiguo 29/08/2012, 14:54
 
Fecha de Ingreso: abril-2011
Mensajes: 1.342
Antigüedad: 11 años, 10 meses
Puntos: 344
Respuesta: Eliminar objeto con delete

El código está bien y hay que utilizar delete, no delete[].

delete[] se utiliza cuando quieres declarar arrays dinámicos, no cuando quieres crear un único objeto, como es tu caso.

Ahora el problema que tenías:

Cuando utilizas delete estás liberando la memoria del objeto al que apuntas, pero el puntero sigue teniendo valor, es decir, tiene apuntada todavía la dirección de memoria y eso te permite realizar la llamada a Saludo, aunque es altamente probable que te dé errores si usas atributos del objeto en el método al que llamas, no así cuando lo único que haces es imprimir una cadena por pantalla.

Para que no puedas llamar al método tienes que poner a null el puntero.

Un saludo.
  #7 (permalink)  
Antiguo 29/08/2012, 15:25
 
Fecha de Ingreso: julio-2011
Ubicación: Querétaro México
Mensajes: 34
Antigüedad: 11 años, 8 meses
Puntos: 0
Respuesta: Eliminar objeto con delete

Cita:
Iniciado por alexg88 Ver Mensaje
El código está bien y hay que utilizar delete, no delete[].

delete[] se utiliza cuando quieres declarar arrays dinámicos, no cuando quieres crear un único objeto, como es tu caso.

Ahora el problema que tenías:

Cuando utilizas delete estás liberando la memoria del objeto al que apuntas, pero el puntero sigue teniendo valor, es decir, tiene apuntada todavía la dirección de memoria y eso te permite realizar la llamada a Saludo, aunque es altamente probable que te dé errores si usas atributos del objeto en el método al que llamas, no así cuando lo único que haces es imprimir una cadena por pantalla.

Para que no puedas llamar al método tienes que poner a null el puntero.

Un saludo.
Código:
int main()
{
  
  Bot * bot;
  
  bot=new Bot();
   	
  bot->Saluda(); 	 // primera llamada
  
  delete bot;              // liberando objeto
  
  bot=NULL;             //poniendo puntero bot a NULL
  
  bot->Saluda();        // segunda llamada ( sigue siendo posible llamarlo )
  
  return 0;
}

pero sigue siendo posible llamarlo ):. ¿ Es a esto lo que te referías con poner bot a NULL? . Disculpa mi ignorancia ):.
  #8 (permalink)  
Antiguo 29/08/2012, 15:51
 
Fecha de Ingreso: agosto-2012
Mensajes: 30
Antigüedad: 10 años, 7 meses
Puntos: 3
Respuesta: Eliminar objeto con delete

Hola Tortoiseius

alexg88 tiene razon, me he rayado un poco. Gracias alexg88 por recordarmelo.

Te dejo algo que encontre al respecto. Creo que aclara estas dudas

[URL="http://trucosinformaticos.wordpress.com/2012/01/29/asignar-null-a-referencias-no-utilizadas/"]http://trucosinformaticos.wordpress.com/2012/01/29/asignar-null-a-referencias-no-utilizadas/[/URL]

Saludos
  #9 (permalink)  
Antiguo 29/08/2012, 15:58
 
Fecha de Ingreso: abril-2011
Mensajes: 1.342
Antigüedad: 11 años, 10 meses
Puntos: 344
Respuesta: Eliminar objeto con delete

Bueno,

He mirado un poco y lo que pasa es que el comportamiento al llamar a un método desde un puntero nulo es indeterminado. Esto quiere decir que, ependiendo de unas circunstancias, puede dar error y, dependendiendo de otras, no.

Lo aconsejable es no realizar ninguna llamada con ese puntero una vez utilizado el delete.

Te dejo un extracto traducido libremente de un texto que he encontrado y define muy bien lo que pasa:

Cita:
Se podría pensar que, al llamar a un método desde un puntero a un objeto, se desferenciaría el puntero (es decir, acceder al objeto) y causaría un error. En la práctica, si la función no es virtual, el compilador convierte esa llamada a una función normal en la que se pasa el puntero como el primer parámetro de esta.

Si el método no hace referencia a las atributos o algún método virtual, esta llamada, en realidad, podría tener éxito sin dar ningún tipo de error.
El éxito de la llamada entra dentro de lo que podemos llamar un comportamiento "indeterminado"
Un saludo
  #10 (permalink)  
Antiguo 29/08/2012, 21:22
 
Fecha de Ingreso: julio-2011
Ubicación: Querétaro México
Mensajes: 34
Antigüedad: 11 años, 8 meses
Puntos: 0
Respuesta: Eliminar objeto con delete

Ya he captado el tema. Muchas garcias por sus aportes LucasMax y Alexg , lo agradezco enserio.

Cita:
La regla de oro de punteros liberados

En conclusión: Si liberas memoria, asigna NULL al puntero.
Saludos !.

Etiquetas: delete, objetos-clases, operador
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 16:05.