elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Introducción a Git (Primera Parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Punteros fantasmas... (asi le puse yo)..
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: 1 [2] Ir Abajo Respuesta Imprimir
Autor Tema: Punteros fantasmas... (asi le puse yo)..  (Leído 4,979 veces)
Loretz

Desconectado Desconectado

Mensajes: 117


Ver Perfil
Re: Punteros fantasmas... (asi le puse yo)..
« Respuesta #10 en: 12 Febrero 2019, 01:36 am »

Citar
tengo que imaginar al delete como un interruptor que desactiva el espacio de memoria y al new como que lo activa..
Casí que es así, no vas a encontrar "activar" pero sí "reclamar", e incluso "allocar" (puaj), la palabra apropiada en el lenguaje C++ es el verbo inglés "allocate".

Si te fijas en la documentación (por ejemplo, en un sitio que no es el del comité estándar pero que todo el mundo tiene a mano: https://en.cppreference.com/w/cpp/memory/new/operator_delete
Verás que el operator delete es toda una familia de funciones, dedicadas a liberar (deallocate) la memoria que se haya pedido con su correspondiente new.

Como ves, delete necesita el nombre de una variable para saber qué liberar, si no hay variable no habrá delete. Por ejemplo, una forma de no liberar nunca memoria asignada (capturada, allocated) con new puede ser:
Código:
void f() { new int; }
Aquí new int; reserva un espacio sizeof(int) en la memoria libre (digamos... 4 bytes), que jamás podrá liberar ningún delete, porque ni nombre tiene el pobre.

Haciendo algo más razonable:
Código:
void g() { int* i = new int; }
Ahora, al salir de g(), la variable i va a morir (es una variable local que termina su vida acotada a su ámbito), pero una copia temporal de esa i queda para ser devuelta como un temporal por la llamada a g().

Por eso es que tiene sentido hacer:
Código:
int* p = g();
porque ahora p va a tener el valor de ese temporal que devolvió g().

Si se hubiera hecho sólo:
Código:
g();
una llamada a g() sin asignar su valor devuelto a ninguna variable de tipo int*, se hubieran perdido esos 4 bytes irremediablemente.

pero después de
Código:
int* i = new int;
se podría hacer perfectamente
Código:
int* j = i;
int* k = j;
de este modo los tres punteros apuntan al mismo espacio de memoria. E invocando un delete en cualquiera de ellos se liberarán esos 4 bytes tomados por new. Puedes hacer, por ejemplo:
Código:
delete k;

Lo que no puedes hacer (bueno, puedes, pero el sistema operativo sabrá tratarte como te mereces) es invocar a delete en más de uno de esos, porque estarías tratando de devolver dos o tres veces la memoria que se reclamó una sola vez. Un new y tres deletes, no te atrevas.

Como este tipo de errores siempre fue frecuente y catastrófico, el C++ actual evita el uso de new / delete, y sanseacabó. unique_ptr y shared_ptr son tus amigos.









En línea

digimikeh

Desconectado Desconectado

Mensajes: 191


Ver Perfil
Re: Punteros fantasmas... (asi le puse yo)..
« Respuesta #11 en: 12 Febrero 2019, 02:18 am »

Perfecto, y esos dos últimos que mencionaste (unique_ptr y shared_ptr) serian punteros inteligentes no ?..


En línea

Dungeons & dragons;
dragons.Attack();
CalgaryCorpus


Desconectado Desconectado

Mensajes: 323


Ver Perfil WWW
Re: Punteros fantasmas... (asi le puse yo)..
« Respuesta #12 en: 12 Febrero 2019, 02:27 am »

Hay un error en lo especificado antes:

En este codigo,

Código
  1.  
  2. int * sumar(int a, int b){
  3.     int * psuma = new int;
  4.     *psuma = a + b;
  5.     return psuma;
  6.  
  7. }
  8.  
  9. int main (){
  10.     int a = 5;
  11.     int b = 10;
  12.  
  13.     int * punteroSuma = new int;    //modificado el nombre
  14.     punteroSuma = sumar(a, b);
  15.  
  16.     delete punteroSuma;      //aqui se elimina psuma, punteroSuma o ambos?
  17. }
  18.  
  19.  
En línea

Aqui mi perfil en LinkedIn, invitame un cafe aqui
CalgaryCorpus


Desconectado Desconectado

Mensajes: 323


Ver Perfil WWW
Re: Punteros fantasmas... (asi le puse yo)..
« Respuesta #13 en: 12 Febrero 2019, 02:28 am »

Hay un error en lo especificado antes:

En el codigo que preguntas

Código
  1.  
  2. int * sumar(int a, int b){
  3.     int * psuma = new int;
  4.     *psuma = a + b;
  5.     return psuma;
  6.  
  7. }
  8.  
  9. int main (){
  10.     int a = 5;
  11.     int b = 10;
  12.  
  13.     int * punteroSuma = new int;    //modificado el nombre
  14.     punteroSuma = sumar(a, b);
  15.  
  16.     delete punteroSuma;      //aqui se elimina psuma, punteroSuma o ambos?
  17. }
  18.  
  19.  

al asignar punteroSuma el resultado de sumar(), se pierde el valor que habias asignado antes.
Esa memoria no la estas liberando, ni se liberara en el delete del final.
En línea

Aqui mi perfil en LinkedIn, invitame un cafe aqui
digimikeh

Desconectado Desconectado

Mensajes: 191


Ver Perfil
Re: Punteros fantasmas... (asi le puse yo)..
« Respuesta #14 en: 13 Febrero 2019, 04:28 am »

No te entendi, cual es el valor que se pierde que había asignado antes?..

EDIT:

Ah!, te refieres a que no debí haber escrito :

Código
  1. int * punteroSuma = new int;

sino:

Código
  1. int * punteroSuma = sumar(a, b);

directamente, verdad?...

Es como que cuando solicité memoria al declarar punteroSuma, esa memoria la dejé botada y pasé el puntero al valor de retorno de Suma.. creo que a eso te refieres...

« Última modificación: 13 Febrero 2019, 04:31 am por digimikeh » En línea

Dungeons & dragons;
dragons.Attack();
K-YreX
Moderador
***
Desconectado Desconectado

Mensajes: 1.008



Ver Perfil
Re: Punteros fantasmas... (asi le puse yo)..
« Respuesta #15 en: 13 Febrero 2019, 05:13 am »

Exacto, sobra el reservar memoria en el <main>. Imagina que cuando usas <new> compras un almacén para guardar "datos" y cuando ya no lo necesitas usas <delete> para venderlo. Un puntero guarda la dirección del almacén.

En tu caso la función <sumar()> compra un almacén, guarda la suma en él y te envía la dirección donde tienes tu almacén. Entonces en el <main> lo que haces es guardar la dirección que te envía la función <sumar()> en el puntero nuevo. No necesitas comprar otro almacén. Porque si compras otro almacén en el <main> y donde tienes guardada la dirección del nuevo almacén, guardas la dirección del almacén que compraste en la función <sumar()>, ya no sabes donde está el último almacén que has comprado. Y si no sabes donde lo tienes, no puedes venderlo... :-\

No sé si queda claro con esto pero es el mejor símil que se me ha ocurrido :-X
En línea

Código
  1. cout << "Todos tenemos un defecto, un error en nuestro código" << endl;
digimikeh

Desconectado Desconectado

Mensajes: 191


Ver Perfil
Re: Punteros fantasmas... (asi le puse yo)..
« Respuesta #16 en: 13 Febrero 2019, 13:15 pm »

buen punto... lo tendré en cuenta la siguiente vez..  :)
En línea

Dungeons & dragons;
dragons.Attack();
Páginas: 1 [2] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Duda Punteros Dobles/Array de punteros
Programación C/C++
MisterJava 2 5,212 Último mensaje 30 Diciembre 2012, 20:19 pm
por MisterJava
Punteros dobles / Punteros a puntero.
Programación C/C++
NOB2014 5 8,473 Último mensaje 13 Abril 2016, 16:00 pm
por MAFUS
Redes Fantasmas « 1 2 »
Hacking
SantosGamer 13 11,450 Último mensaje 5 Noviembre 2022, 22:56 pm
por SantosGamer
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines