Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: NOB2014 en 3 Mayo 2016, 21:43 pm



Título: [Solucionado] Liberar memoria de 2 punteros apuntando a la misma dirección(C)
Publicado por: NOB2014 en 3 Mayo 2016, 21:43 pm
Hola, gente. -
¿Es necesario liberar los 2 punteros por separado?, como lo hago en el código que dejo a continuación o es suficiente con liberar el puntero que devuelve malloc (tengo claro que malloc retorna un puntero void). -

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. int main( void ){
  6. char *string1, *string2;
  7. string1 = (char*) malloc(16);
  8. strcpy(string1, "0123456789AB");
  9.  
  10. string2 = realloc(string1, 8);
  11. printf("string1 Valor: %p [%s]\n", string1, string1);
  12. printf("string2 Valor: %p [%s]\n", string2, string2);
  13.  
  14.  
  15. free(string1);
  16. free(string2);
  17.  
  18. return 0;
  19. }

Bueno es todo, espero aclaración.
Un abrazo.


Título: Re: Liberar memoria de 2 punteros apuntando a la misma dirección(malloc/realloc/free
Publicado por: MAFUS en 3 Mayo 2016, 21:54 pm
En este caso, cuándo haces realloc, string1 deja de tener memoria asignada. Hay que verlo como si realloc hiciera internamente un free al puntero que se le pasa. El que veas string1 después del realloc es porqué los datos persisten en la memoria (no se pone a 0), aunque hay que recordar que el sistema ya no la tiene en cuenta por tanto en cualquier momento se puede reescribir.


Título: Re: Liberar memoria de 2 punteros apuntando a la misma dirección(malloc/realloc/free
Publicado por: AlbertoBSD en 3 Mayo 2016, 22:55 pm
Como comenta MAFUS el string1 deja de tener memoria asignada...

aun asi el string1 sigue apuntando a la direccion que originalmente se le asigno y los datos que estaban ahi ahi siguen... el sistema operativo es el que se encarga de ver si lo borra lo asigna o que se yo..

Es deber del usuario no usar ese puntero hasta que se reasigne nuevamente. La memoria que originalmente se asigno podria ser designada a otro apuntador.

Si el apuntador se va a volve a usar hay que igualarlo a NULL para que no nos de un error despues al hacer

if(string1)....

mas info:
http://linux.die.net/man/3/realloc


Título: Re: Liberar memoria de 2 punteros apuntando a la misma dirección(malloc/realloc/free
Publicado por: geeke en 3 Mayo 2016, 22:57 pm
También notar que al llamar a realloc se reasigna un espacio de memoria menor al requerido por la cadena original esto causa un comportamiento indefinido


Título: Re: Liberar memoria de 2 punteros apuntando a la misma dirección(malloc/realloc/free
Publicado por: NOB2014 en 3 Mayo 2016, 23:29 pm
Muchas gracias a los 3 por ocuparse, si entendí bien con hacer free(string2) es suficiente. -
Al releer el tema en un momento dice que si string2 es menor a string1 el administrador del montón tratara de utilizar la misma dirección de memoria y como pude comprobar con este programa la dirección de  string1 es la misma que string2, ¿esto es correcto? o interprete mal. -
Geeke, lo tuyo es lo único que no me queda claro. -

Saludos.


Título: Re: Liberar memoria de 2 punteros apuntando a la misma dirección(malloc/realloc/free
Publicado por: AlbertoBSD en 3 Mayo 2016, 23:37 pm
Si es la misma, depende de la implementan de realloc, en teoria lo mas eficiente es dejar la misma dirección cuando el espacio que se va asignar es menor al previo.

Código:
string1 Valor: 0000000000321380 [0123456789AB]
string2 Valor: 0000000000321380 [0123456789AB]


Título: Re: Liberar memoria de 2 punteros apuntando a la misma dirección(malloc/realloc/free
Publicado por: geeke en 4 Mayo 2016, 00:04 am
Me refiero a que la cadena 0123456789AB tiene mas de 8 caracteres tu reasignas espacio solo para ocho; recuerda que realloc copia todo el contenido del antiguo puntero al nuevo


Título: Re: Liberar memoria de 2 punteros apuntando a la misma dirección(malloc/realloc/free
Publicado por: NOB2014 en 4 Mayo 2016, 00:28 am
En definitiva, lo que pregunte parecería que tendría una respuesta obvia, solo que quería estar más seguro teniendo la palabras de Uds. los expertos.-
AlbertoBSD, gracias nuevamente.

Un abrazo.


Título: Re: Liberar memoria de 2 punteros apuntando a la misma dirección(malloc/realloc/free
Publicado por: AlbertoBSD en 4 Mayo 2016, 02:51 am
Acabo de confirmar al revisar el codigo fuente derealloc y si el espacio de memoria solicitado es menor que el anterior NO mueve ningun byte de memoria, solo actualiza en su lista de punteros que el puntero dado utiliza menos memoria.

Lo pueden revisar en
http://www.scs.stanford.edu/histar/src/pkg/uclibc/libc/stdlib/malloc-standard/realloc.c

La parte en cuestion es esta:
Código
  1. if ((unsigned long)(oldsize) >= (unsigned long)(nb)) {
  2.    /* already big enough; split below */
  3.    newp = oldp;
  4.    newsize = oldsize;
  5. }
  6.  
  7. else {
  8. ...
  9.  


Título: Re: Liberar memoria de 2 punteros apuntando a la misma dirección(malloc/realloc/free
Publicado por: Eternal Idol en 4 Mayo 2016, 03:28 am
http://www.cplusplus.com/reference/cstdlib/realloc/

Citar
void* realloc (void* ptr, size_t size);

Reallocate memory block
Changes the size of the memory block pointed to by ptr.

The function may move the memory block to a new location (whose address is returned by the function).

La palabra clave ahi es may, no siempre se mueve el bloque de memoria.

Acabo de confirmar al revisar el codigo fuente derealloc

Una aclaracion: ese es un codigo fuente, lo que vale es lo que dice el standard, todo lo demas son implementaciones.


Título: Re: Liberar memoria de 2 punteros apuntando a la misma dirección(malloc/realloc/free
Publicado por: geeke en 4 Mayo 2016, 04:57 am
si el espacio de memoria solicitado es menor que el anterior NO mueve ningun byte de memoria

Como ya han indicado no existe ninguna garantía de que realloc retorné la misma dirección o una nueva esto no implica que dependa de que el nuevo tamaño sea menor que el inicial.


Título: Re: Liberar memoria de 2 punteros apuntando a la misma dirección(malloc/realloc/free
Publicado por: AlbertoBSD en 4 Mayo 2016, 05:41 am
Gracias Eternal Idol ya estoy enterado :) , tu siempre tan meticuloso con los estándares  ;-) ;-)

Aun asi la implementacion de realloc que me toco ver coincide con que es mas eficiente dejar la memoria tal cual en ese caso especifico.

Saludos a todos!



Título: Re: Liberar memoria de 2 punteros apuntando a la misma dirección(malloc/realloc/free
Publicado por: NOB2014 en 4 Mayo 2016, 14:12 pm
Hola y que tengan un muy buen día.
Voy a intentar un resumen, lo que este equivocado, por favor, corríjanlo. -
Con liberar la memoria de string2, es suficiente dado que de string1 se encarga realloc, si no es el fin del programa deberíamos igualar los punteros string1 y string 2 a NULL. -
En el futuro voy a hacer preguntas más interesante, me agrada cuando participa el "jefe". -

Muchas gracias a todos y un abrazo.


Título: Re: Liberar memoria de 2 punteros apuntando a la misma dirección(malloc/realloc/free
Publicado por: MAFUS en 4 Mayo 2016, 14:41 pm
Correcto.