¿Qué sucede con los datos en la memoria desasignados por free()?

6 minutos de lectura

¿Qué sucede con los datos que están presentes en una ubicación de memoria que acaba de ser liberada por un free() ? ¿Esos datos también se eliminan y la memoria ahora tendrá un valor de basura? ¿O esos datos aún persisten allí hasta que se almacenan nuevos datos en esa ubicación de memoria (en el futuro)?

Quiero decir, para el código a continuación:

int *ptr;
ptr = malloc(sizeof(int));
*ptr = 1;
 // Suppose ptr = 2000
 //Free now
free(ptr);
// My question is what is the value stored in memory address 2000 now ?
// Is it still '1' or some garbage value ?

  • La norma no especifica eso. Sólo dice que algunos usos de ptr después de la llamada a free es un comportamiento indefinido.

    – R Sahu

    12 de abril de 2015 a las 4:55

  • Ambos escenarios que mencionó son posibles entre muchos otros, incluido el acceso a los datos a través de ese puntero, lo que resulta en una falla de segmentación. Es un comportamiento indefinido (UB). Déjalo ir

    – chux – Reincorporar a Monica

    12 de abril de 2015 a las 4:56


El resultado es impredecible. Hay varias opciones que pueden suceder. El punto es que no puedes confiar en ningún comportamiento de la memoria liberada por free()

Algunos ejemplos:

  • la memoria puede estar intacta (permanecer igual que está con los mismos datos).
  • Se puede asignar a otra asignación de memoria, en cuyo caso se puede sobrescribir en cualquier momento.
  • Se puede poner a cero.
  • La página que contiene la memoria se puede devolver al sistema operativo, eliminándola del mapa de memoria de su proceso, haciendo que su programa se bloquee si intenta acceder a ella.

  • Con la nota de que es extremadamente, extremadamente poco probable que se ponga a cero. Incluso en el último caso, lo más probable es que permanezca como estaba durante un tiempo, lo que permite que cualquier proceso a nivel de kernel lo lea a voluntad.

    – Ciego

    12 de abril de 2015 a las 5:19

  • algunos asignadores de memoria ponen a cero la memoria liberada, ya sea por seguridad o para prepararla para asignaciones que esperan memoria puesta a cero. Algunos hacen otras cosas misteriosas sobre las que solo podemos especular.

    – Codificador de longitud variable

    12 de abril de 2015 a las 5:37

  • Lo mismo ocurre con la asignación por razones de seguridad. Cuando el programa solicita algo de memoria, el sistema operativo no puede simplemente proporcionar una parte de la memoria libre. Esa memoria (o página) puede ser propiedad del sistema operativo o de un proceso crítico antes de la asignación y entregar la memoria sin modificar/poner a cero haría vulnerable al último propietario.

    – holgac

    12 de abril de 2015 a las 9:11

  • Acabo de enterarme de que en x86 y x86_64, el kernel de Linux 3.18.1 pone a cero la memoria en la llamada a brkcual malloc llamadas Entonces, cada vez malloc solicita memoria del sistema operativo, la memoria devuelta se pone a cero. Tenga en cuenta que malloc generalmente solicita más del sistema operativo y malloc y free tienen su propia gestión de memoria. Por lo tanto, es posible que las llamadas a cualquiera de ellos no den como resultado una llamada al sistema, por lo que no puede garantizar su valor. Pero puede garantizar que es cero o su basura.

    – holgac

    12 de abril de 2015 a las 9:42

No se define si el valor se sobrescribe o no. Una vez free se le permite dejar la memoria como está o puede sobrescribirla, pero si está interesado en la seguridad, debe sobrescribirla usted mismo antes de desasignarla. Hablando de desasignación, free no tiene que devolver la memoria al sistema operativo y, de hecho, en muchos casos no lo hará, sino que mantendrá la memoria asignada a su programa para que la próxima vez que llame malloc simplemente puede devolverle la misma memoria y evitar tener que hacer más llamadas al sistema, ya que el tiempo que toma la asignación de memoria del sistema operativo generalmente se considera un uso menos eficiente de los recursos que el programa que mantiene un poco más de memoria asignada. necesidades.

  • Usted sabe que la gestión de la memoria dinámica está a cargo del SO. Entonces, aunque puede ser una buena práctica eliminar los datos sensibles contenidos en la memoria antes de liberarlos, ¡sabe que quien tiene el control del sistema operativo puede conocer todos los datos que maneja! Más bien, creo que es una buena práctica destruir los datos sensibles inmediatamente después de que se hayan utilizado, ¡lo que hace que disminuya el tiempo en que los datos son visibles!

    – Sir Jo Negro

    12 de abril de 2015 a las 13:41

avatar de usuario
Señor jo negro

¡Sé que usando la función C free() se libera la memoria utilizada, pero no se modifica ni el puntero ni el valor contenido en la memoria! free() solo dice que la memoria puede usarse para otros fines. (Puede que algunas implementaciones de bibliotecas limpien la memoria liberada o el valor del puntero, ¡pero esto no debería ser el estándar!)

Probé el siguiente código con gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2

int main(void)
{
    int *i,j;

    i=malloc(100*sizeof(int));

    for(j=0;j<100;j++)
        i[j]=j+1;

    printf("%p %d\n",i,i[0]);

    free(i);

    printf("%p %d\n",i,i[0]);

    return 0;
}

Los resultados de salida (como esperaba) son:

0x1de2010 1
0x1de2010 1

Malloc() es una función de biblioteca. La respuesta depende de cómo se implemente la biblioteca.

La mayoría (si no todos) los mallocs anteponen un encabezado al bloque de memoria devuelto. Esto generalmente se modifica.

Algunos mallocs añaden un tráiler al bloque de memoria y le escriben algo. Esto se utiliza para detectar desbordamientos de búfer.

Algunos frees() sobrescribirán la escritura de la memoria devuelta con algún patrón de bits para detectar escrituras posteriores.

Hay muchos mallocs que puede descargar y vincular con su aplicación para que pueda obtener casi cualquier comportamiento que desee al vincular el malloc que desea con su aplicación.

avatar de usuario
rabi shaw

Depende del compilador. Si está utilizando gcc, después de que el valor libre de esa memoria se convierta en 0.

Aquí hay un código de muestra:

#include<stdio.h>
#include<stdlib.h>

int main ( void )
{
        int *ptr = NULL;
        ptr = malloc (sizeof(int));
        *ptr = 5;
        printf ( "\n value of *ptr = %d", *ptr );
        free ( ptr );
        printf ( "\n value of *ptr = %d", *ptr );

        return ( 0 );
}

o/p:

./a.out

 value of *ptr = 5
 value of *ptr = 0

 ./a.out

 value of *ptr = 5
 value of *ptr = 0

./a.out

 value of *ptr = 5
 value of *ptr = 0

  • @Coronel, ¿puedo saber el motivo de -1?

    – rabi shaw

    12 de abril de 2015 a las 5:11

  • Creo que la razón del downwote es que gcc no garantiza esto. Puede depender de los indicadores de compilación de glibc y los indicadores de optimización de gcc, o puede ser solo una coincidencia.

    – holgac

    12 de abril de 2015 a las 9:06

avatar de usuario
coronel treinta y dos

Desreferenciar un freeEl puntero d conduce a un comportamiento indefinido, lo que significa que se permite que suceda cualquier cosa.

Lo más probable es que obtenga un valor de basura, pero también puede desencadenar una falla de segmentación, lo que bloqueará su programa. Aun así, ninguno de esos comportamientos está garantizado y no debe confiar en ellos.

  • @Coronel, ¿puedo saber el motivo de -1?

    – rabi shaw

    12 de abril de 2015 a las 5:11

  • Creo que la razón del downwote es que gcc no garantiza esto. Puede depender de los indicadores de compilación de glibc y los indicadores de optimización de gcc, o puede ser solo una coincidencia.

    – holgac

    12 de abril de 2015 a las 9:06

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad