Me gustaría saber cuál es la diferencia entre la asignación de memoria estática y la asignación de memoria dinámica.
¿Podría explicar esto con algún ejemplo?
Me gustaría saber cuál es la diferencia entre la asignación de memoria estática y la asignación de memoria dinámica.
¿Podría explicar esto con algún ejemplo?
Respuestas:
Hay tres tipos de asignación: estática, automática y dinámica.
Asignación estática significa que la memoria para sus variables se asigna cuando se inicia el programa. El tamaño se fija cuando se crea el programa. Se aplica a variables globales, variables de ámbito de archivo y variables calificadas con static
funciones internas definidas.
La asignación automática de memoria ocurre para las variables (no estáticas) definidas dentro de las 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 adicional 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 finaliza la función.
void func() {
int i; /* `i` only exists during `func` */
}
La asignación de memoria dinámica es un poco diferente. Ahora controla el tamaño exacto y la vida útil de estas ubicaciones de memoria. Si no lo libera, se producirá una pérdida de memoria, lo que puede hacer que su aplicación se bloquee, ya que en algún momento, 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 terminado. Cuando haya terminado con la memoria, debe liberarla:
free(mem);
Esta es una pregunta estándar de la entrevista:
Es la memoria asignada en tiempo de ejecución utilizando calloc()
, malloc()
y amigos. A veces también se la conoce como memoria "heap", aunque no tiene nada que ver con la referencia de la estructura de datos del montón .
int * a = malloc(sizeof(int));
La memoria del montón es persistente hasta free()
se llama. En otras palabras, usted controla la vida útil de la variable.
Esto es lo que se conoce comúnmente como memoria de 'pila' y se asigna cuando ingresa un nuevo alcance (generalmente cuando se inserta una nueva función en la pila de llamadas). Una vez que se sale 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 alcance no significa necesariamente función. Los ámbitos pueden anidar dentro de una función y la variable estará dentro del ámbito 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 una cuerda sistema , estará en la pila o se registrará para la optimización)
Se asigna en tiempo de compilación * , y la vida útil de una variable en la memoria estática es la vida útil del programa. .
En C, la memoria estática se puede asignar usando el static
palabra clave. El alcance es solo la unidad de compilación.
Las cosas se vuelven más interesantes cuando extern
se considera la palabra clave . Cuando extern
se define una variable, el compilador le asigna memoria. Cuando extern
se declara una variable , el compilador requiere que la variable esté definida otro lugar. No declarar / definir extern
variables provocará problemas de vinculación, mientras que no declarar / definir static
variables provocará 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
hay dos clases separadas de variables en C.
extern int a; /* Declaration */
int a; /* Definition */
Es algo confuso decir que la memoria estática se asigna en el momento de la compilación, especialmente si empezamos a considerar que la máquina de compilación y la máquina host podrían no ser iguales o ni siquiera estar en la misma arquitectura.
Puede ser mejor pensar que la asignación de memoria estática la maneja el compilador lugar de asignarla en tiempo de compilación .
Por ejemplo, el compilador puede crear una gran data
sección en el binario compilado y cuando el programa se carga en la memoria, la dirección dentro deldata
segmento 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 código de inicialización que asignará 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 utilizan la heurística para decidir cuál de estas opciones utilizar. Puede probar esto usted mismo escribiendo un pequeño programa en C que asigne una gran matriz estática de elementos de 10k, 1m, 10m, 100m, 1G o 10G. Para muchos compiladores, el tamaño binario seguirá creciendo linealmente con el tamaño de la matriz y más allá de cierto punto,
La última clase de memoria son las variables de 'registro'. Como era de esperar, las variables de registro deben asignarse en el registro de una CPU, pero la decisión se deja en manos del compilador. No puede convertir una variable de registro en una referencia utilizando address-of.
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 a la hora de elegir qué variables deben incluirse en los registros :)
int * a = malloc(sizeof(*a));
lugar, sugeriría evitar repetir el tipo de a
. Esto hace las cosas mucho más fáciles si alguna vez el tipo de a
cambios.
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, esta La forma de asignar un valor de 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 dinámica de memoria: utiliza funciones como malloc () o calloc () para obtener memoria dinámicamente.Si estas funciones se usan para obtener memoria dinámicamente y los valores devueltos por estas funciones se asignan a variables de puntero, dichas asignaciones se conocen como memoria dinámica. La asignación de memoria se asigna durante el tiempo de ejecución.
Asignación de memoria estática:
Asignación de memoria dinámica:
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 realizan acciones de asignación o desasignación de memoria durante la ejecución.
Los enlaces de memoria se establecen y destruyen durante la ejecución.
Las variables permanecen asignadas de forma permanente.
Asignado solo cuando la unidad de programa está activa.
Implementado usando pilas y montones.
Implementado usando segmentos de datos.
Se necesita un puntero para acceder a las variables.
Sin necesidad de punteros asignados dinámicamente.
Ejecución más rápida que Dynamic.
Ejecución más lenta que estática.
Se requiere más espacio de memoria.
Requiere menos espacio de memoria.
La asignación de memoria estática se asigna memoria antes de la ejecución del programa durante el tiempo de compilación. La ubicación de memoria dinámica es memoria ubicada durante la ejecución del programa en tiempo de ejecución.
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 el montón.
int *a = malloc(sizeof(int) * 10);
y este último debería estar libre d ya que no hay un recolector de basura (GC) en C.
free(a);