Modelo de memoria en lenguaje C

El modelo de memoria en lenguaje C  es un sistema de almacenamiento de objetos en lenguaje C [1] .

La forma en que se almacena un objeto en C define su vida útil, la parte del tiempo de ejecución del programa durante la cual existe el objeto o se reserva espacio para él. El objeto tiene una dirección permanente y conserva su último valor. Está prohibido acceder a un objeto que ha dejado de existir, mientras que si se utilizó un puntero al trabajar con un objeto, su valor permanece indefinido.

Hay tres formas de almacenar objetos [1] : automático, estático y dinámico .

Propiedad Auto Estático Dinámica
Anuncio Objeto sin ataduras y sinstatic Tiene vinculación interna o externa , o se declara con un calificadorstatic Resaltado conmalloc
tiempo de existencia El bloque en el que se declara el objeto. Todo el tiempo que el programa se está ejecutando De llamada mallocen llamadafree
Inicialización Falta si no hay una inicialización explícita Ocurre una vez antes de que comience el programa. parcialmente en casocalloc
El tamaño Fijo, inmutable Fijo, inmutable Cualquiera, cambiable
Colocación típica Registros de pila o procesador Segmento de memoria separado montón

Un objeto estático se puede inicializar explícitamente o se puede usar la inicialización predeterminada.

Al usar la función, calloctodos los objetos son nulos excepto los números de punto flotante y los punteros [2] .

Las expresiones sin valor l que se refieren a una matriz que es miembro de una estructura ( struct) o unión ( union) tienen un tiempo de vida limitado por la evaluación de esa expresión [1] .

Las cadenas C que inicializan punteros char*tienen un tipo de almacenamiento estático y no deben cambiarse [3] .

Memoria dinámica

Ningún objeto puede estar en la memoria dinámica sin instrucciones explícitas del programador. Para trabajar con memoria dinámica, existen las funciones malloc, calloc, reallocy free. Dado que las funciones que asignan memoria toman un tamaño en una variable de tipo size_t, la cantidad máxima de memoria asignada está limitada SIZE_T_MAX[1] .

Las funciones mallocy callocasignan memoria que, después de su uso, debe liberarse con una llamada a free. Una vez liberado, el valor del puntero permanece indefinido . La función reallocdevuelve un puntero al bloque de memoria modificado, si la solicitud no se puede satisfacer, el tamaño del bloque de memoria no cambia [1] .

#incluir <stdlib.h> void foo ( void ** ptr , size_t size ) { * ptr = realloc ( * ptr , tamaño + 128 ); /* pérdida de memoria si realloc devuelve NULL */ si ( !* punto ) { ... } }

Cuando se trabaja con memoria dinámica, es posible que se produzcan fugas de memoria y errores de bloques dobles.

Ejemplo

#incluir <stdlib.h> #incluir <cadena.h> int estático x ; /* 0 por defecto, existe todo el tiempo */ int estático y = 45 ; /* 45, existe todo el tiempo */ int cnt ( vacío ) { int estático i = 0 ; /* tipo estático, inicializado a cero solo al inicio del programa, no en todas las llamadas de función */ int j = -1 ; /* tipo automático, inicializado cada vez que se llama a la función -1*/ i ++ ; /* aumenta en 1 en la memoria estática cada vez que se llama a la función */ j ++ ; /* incrementa la variable local en 1 */ retorno ( i + j ); /* en la primera llamada desde el inicio del programa, la función devolverá 1, en la segunda llamada 2, ... */ } int principal ( vacío ) { char arr [ 50 ] = "Este es un objeto de duración de almacenamiento automático" ; /* tiene un tipo automático, existe hasta las salidas principales, los 45 elementos iniciales del arreglo se inicializan con los elementos de la cadena con un cero de cierre, el resto son indefinidos */ char * linea = "Línea simple" ; /* tipo automático, existe hasta que sale principal, línea inicializada con puntero a constante */ int y ; /* el valor no está definido, existe hasta que main sale */ int z = 10 ; /* el valor está definido, existe hasta que main sale */ char * ptr ; /* el valor del puntero no está definido */ ptr = malloc ( 50 ); /* el valor por puntero no está definido, el objeto por puntero existe antes de llamar gratis */ strcpy ( ptr , arr ); gratis ( ptr ); devolver 0 ; }

Notas

  1. 1 2 3 4 5 ISO/IEC 9899:1999. 6.2.4 . Consultado el 5 de agosto de 2011. Archivado desde el original el 15 de agosto de 2011.
  2. ISO/IEC 9899:1999 7.20.3 . Consultado el 5 de agosto de 2011. Archivado desde el original el 15 de agosto de 2011.
  3. C Preguntas frecuentes . Consultado el 8 de agosto de 2011. Archivado desde el original el 11 de agosto de 2011.