estatica - memoria dinamica en c
Diferencia entre la asignación de memoria estática y la asignación de memoria dinámica (7)
Asignación de memoria estática. La memoria asignada estará en la pila.
int a[10];
Asignación de memoria dinámica. La memoria asignada estará en montón.
int *a = malloc(sizeof(int) * 10);
y el último debe estar libre, ya que no hay un Recolector de basura (GC) en C.
free(a);
Me gustaría saber cuál es la diferencia entre la asignación de memoria estática y la asignación dinámica de memoria.
¿Podrías explicar esto con algún ejemplo?
Diferencia entre ASIGNACIÓN DE MEMORIA ESTÁTICA Y ASIGNACIÓN DE MEMORIA DINÁMICA
La memoria se asigna antes de que comience la ejecución del programa (durante la compilación).
La memoria se asigna durante la ejecución del programa.
No se realiza ninguna asignación de memoria ni acciones de desasignación durante la ejecución.
Los enlaces de memoria se establecen y destruyen durante la ejecución.
Las variables permanecen asignadas permanentemente.
Asignado solo cuando la unidad de programa está activa.
Implementado usando pilas y montones.
Implementado usando segmentos de datos.
El puntero es necesario para acceder a las variables.
Sin necesidad de punteros asignados dinámicamente.
Ejecución más rápida que dinámica.
Ejecución más lenta que estática.
Más memoria Requiere espacio.
Se requiere menos memoria.
Esta es una pregunta de entrevista estándar:
Asignación de memoria dinámica
La memoria está asignada en tiempo de ejecución usando calloc()
, malloc()
y amigos. A veces también se conoce como memoria "apilada", aunque no tiene nada que ver con la ref estructura de datos del montón.
int * a = malloc(sizeof(int));
La memoria del montón es persistente hasta que se llama a free()
. En otras palabras, usted controla la vida útil de la variable.
Asignación automática de memoria
Esto es lo que comúnmente se conoce como memoria de "pila", y se asigna cuando ingresa un nuevo alcance (generalmente cuando se presiona una nueva función en la pila de llamadas). Una vez que se mueve fuera del alcance, los valores de las direcciones de memoria automáticas no están definidos, y es un error acceder a ellos .
int a = 43;
Tenga en cuenta que el alcance no necesariamente significa función. Los ámbitos pueden anidar dentro de una función, y la variable estará dentro del alcance solo dentro del bloque en el que se declaró. Tenga en cuenta también que no se especifica dónde se asigna esta memoria. (En un sistema en buen estado estará en la pila, o se registra para la optimización)
Asignación de memoria estática
Se asigna en tiempo de compilación, y la vida útil de una variable en memoria estática es la static .
En C, la memoria estática se puede asignar usando la palabra clave static
. El alcance es solo la unidad de compilación.
Las cosas se vuelven más interesantes cuando se considera la palabra clave extern
. Cuando se define una variable extern
, el compilador asigna memoria para ello. Cuando se declara una variable extern
, el compilador requiere que la variable se defina en otro lugar. Si no se declaran / definen las variables extern
se causarán problemas de vinculación, mientras que la falta de declaración / definición de variables static
causará problemas de compilación.
en el alcance del archivo, la palabra clave estática es opcional (fuera de una función):
int a = 32;
Pero no en el alcance de la función (dentro de una función):
static int a = 32;
Técnicamente, extern
y static
son dos clases separadas de variables en C.
extern int a; /* Declaration */
int a; /* Definition */
Registrar memoria
La última clase de memoria son variables de ''registro''. Como se esperaba, las variables de registro se deben asignar en el registro de una CPU, pero la decisión se deja en realidad al compilador. No puede convertir una variable de registro en una referencia mediante el uso de la dirección-de.
register int meaning = 42;
printf("%p/n",&meaning); /* this is wrong and will fail at compile time. */
La mayoría de los compiladores modernos son más inteligentes que usted al elegir qué variables se deben poner en los registros :)
Referencias
- El manual libc
- El lenguaje de programación The C de K & R, Apéndice A, Sección 4.1, "Clase de almacenamiento". ( PDF )
- C11 estándar , sección 5.1.2, 6.2.2.3
- Wikipedia también tiene buenas páginas sobre asignación de memoria estática , asignación de memoria dinámica y asignación de memoria automática
- La página C Dynamic Allocation de la página en Wikipedia
- Esta referencia de administración de memoria contiene más detalles sobre las implementaciones subyacentes para los asignadores dinámicos.
Notas sobre la asignación de memoria estática
Es algo confuso decir que la memoria estática se asigna en tiempo de compilación, especialmente si comenzamos a considerar que la máquina de compilación y la máquina host pueden no ser iguales o no estar en la misma arquitectura.
Puede ser mejor pensar que la asignación de la memoria estática es manejada por el compilador en lugar de asignarse en tiempo de compilación . Por ejemplo, el compilador puede crear una gran sección de data
en el binario compilado y cuando el programa se carga en la memoria, la dirección dentro del segmento de data
del programa se utilizará como la ubicación de la memoria asignada. Esto tiene la marcada desventaja de hacer que el binario compilado sea muy grande si usa mucha memoria estática. Es posible escribir un binario de varios gigabytes generado a partir de menos de media docena de líneas de código. Otra opción es que el compilador inyecte el código de inicialización que asignará la memoria de alguna otra manera antes de que se ejecute el programa. Este código variará según la plataforma de destino y el sistema operativo. En la práctica, los compiladores modernos usan la heurística para decidir cuál de estas opciones usar. Puede probarlo usted mismo escribiendo un pequeño programa en C que asigne una matriz estática grande de 10k, 1m, 10m, 100m, 1G o 10G elementos. Para muchos compiladores, el tamaño binario seguirá creciendo linealmente con el tamaño de la matriz, y pasado un cierto punto, se reducirá nuevamente a medida que el compilador use otra estrategia de asignación.
Hay tres tipos de asignación: estática, automática y dinámica.
La asignación estática significa que la memoria para sus variables se asigna cuando se inicia el programa. El tamaño es fijo cuando se crea el programa. Se aplica a variables globales, variables de alcance de archivo y variables calificadas con funciones internas definidas static
.
La asignación automática de memoria ocurre para variables (no estáticas) definidas dentro de funciones, y generalmente se almacena en la pila (aunque el estándar C no exige que se use una pila). No tiene que reservar memoria extra usándolos, pero por otro lado, también tiene un control limitado sobre la vida útil de esta memoria. Por ejemplo: las variables automáticas en una función solo están ahí hasta que la función finaliza.
void func() {
int i; /* `i` only exists during `func` */
}
La asignación dinámica de memoria es un poco diferente. Ahora controla el tamaño exacto y la duración de estas ubicaciones de memoria. Si no lo libera, se encontrará con fugas de memoria, lo que puede hacer que su aplicación se bloquee, ya que en algún punto del tiempo, el sistema no puede asignar más memoria.
int* func() {
int* mem = malloc(1024);
return mem;
}
int* mem = func(); /* still accessible */
En el ejemplo superior, la memoria asignada sigue siendo válida y accesible, aunque la función haya finalizado. Cuando haya terminado con la memoria, debe liberarla:
free(mem);
La asignación de memoria estática se asigna a la memoria antes de ejecutar el programa pf durante el tiempo de compilación. La asignación de memoria dinámica es memoria asignada durante la ejecución del programa en tiempo de ejecución.
Asignación de memoria dinámica : la memoria se asigna durante el tiempo de ejecución en el montón. Esto se usa cuando la cantidad (tamaño) de memoria es variable y solo se conoce durante el tiempo de ejecución. La asignación dinámica se logra usando ciertas funciones como malloc (), calloc (), realloc (), libre en C y "nuevo", "eliminar" en C ++.
Asignación de memoria estática : memoria asignada en tiempo de compilación en la pila u otros segmentos de datos. Esto se usa cuando la cantidad (tamaño) de memoria es estática / constante y se conoce durante el tiempo de compilación.
Asignación de memoria estática: el compilador asigna el espacio de memoria requerido para una variable declarada. Al usar la dirección del operador, se obtiene la dirección reservada y esta dirección puede asignarse a una variable de puntero. Dado que la mayoría de las variables declaradas tienen memoria estática, esto La forma de asignar el valor del puntero a una variable de puntero se conoce como asignación de memoria estática. la memoria se asigna durante el tiempo de compilación.
Asignación de memoria dinámica: utiliza funciones como malloc () o calloc () para obtener memoria dinámicamente. Si estas funciones se utilizan para obtener memoria dinámicamente y los valores devueltos por estas funciones se asignan a variables de puntero, tales asignaciones se conocen como memoria dinámica allocation.memory se asigna durante el tiempo de ejecución.