Diferencia entre la asignación de memoria estática y la asignación de memoria dinámica

Respuestas:

92

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 staticfunciones 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);
Constantinius
fuente
2
Seguro que tienes control sobre la vida útil de las variables ... eres tú quien decide el alcance, ¿verdad?
Luchian Grigore
Por supuesto, pero eso no es lo que quise decir. No se puede extender la vida útil de las variables para sobrevivir a su alcance. Pero tal vez debería aclarar eso en mi respuesta. Gracias
Constantinius
5
-1 Esta respuesta es incorrecta. Confundes variables estáticas y automáticas .
brice
2
Su propia oración dice: " La asignación estática significa que la memoria para sus variables se asigna automáticamente " Esto es incorrecto . Eche un vistazo a lo que la página del manual de la libc de GNU tiene que decir al respecto.
brice
1
@EliBendersky Está reformulado ahora. Compruebe si es correcto ahora.
Suraj Jain
116

Esta es una pregunta estándar de la entrevista:

Asignación de memoria dinámica

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.

Asignación automática de memoria

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)

Asignación de memoria estática

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 externse considera la palabra clave . Cuando externse define una variable, el compilador le asigna memoria. Cuando externse declara una variable , el compilador requiere que la variable esté definida otro lugar. No declarar / definir externvariables provocará problemas de vinculación, mientras que no declarar / definir staticvariables 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, externy statichay dos clases separadas de variables en C.

extern int a; /* Declaration */
int a; /* Definition */

* Notas sobre la asignación de memoria estática

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 datasección en el binario compilado y cuando el programa se carga en la memoria, la dirección dentro deldatasegmento 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,

Registrar memoria

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 :)

Referencias:

brice
fuente
3
Nota: en su 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 acambios.
Shahbaz
1
Actualmente se llama montón, pero no tiene nada que ver con la estructura de datos del montón. Heap en este caso significa un lugar desordenado
dinámico
2
"Asignación de memoria estática ... se asigna en tiempo de compilación" ¿Quiere decir que el tamaño de asignación se determina en tiempo de compilación? ¿No ocurriría la reserva de la memoria solo en tiempo de ejecución?
lf215
2

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.

Rajeev Kumar
fuente
2

Asignación de memoria estática:

  • Las variables se asignan de forma permanente
  • La asignación se realiza antes de la ejecución del programa.
  • Utiliza la estructura de datos llamada pila para implementar la asignación estática.
  • Menos eficiente
  • No hay capacidad de reutilización de la memoria

Asignación de memoria dinámica:

  • Las variables se asignan solo si la unidad del programa se activa
  • La asignación se realiza durante la ejecución del programa.
  • Utiliza la estructura de datos llamada montón para implementar la asignación dinámica
  • Más eficiente
  • Hay capacidad de reutilización de la memoria . La memoria se puede liberar cuando no se requiere
vinay
fuente
1
"Asignación de memoria estática [...] Utiliza la estructura de datos llamada pila para implementar la asignación estática" No , eso es incorrecto y engañoso. consulte mi publicación para ver la diferencia entre la asignación automática y estática. La memoria estática puede usar la pila. Esto depende en gran medida de la implementación y se pueden utilizar múltiples estrategias para la misma implementación. Tampoco estoy seguro de a qué te refieres con "menos eficiente". @Trieu Toan, cambió el significado de esta respuesta con una mala edición.
brice
1

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.

Ebenezer
fuente
1
la asignación de memoria estática se asigna en la pila mientras que la asignación de memoria dinámica se asigna en el montón
Usman Kurd
@UsmanKurd Eso es generalmente incorrecto con respecto a la memoria estática. Mira mi respuesta.
brice
0

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.

Ritu maheswari
fuente
-1

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);
onemach
fuente