Différence entre l'allocation de mémoire statique et l'allocation de mémoire dynamique

Réponses:

91

Il existe trois types d'allocation: statique, automatique et dynamique.

L'allocation statique signifie que la mémoire de vos variables est allouée au démarrage du programme. La taille est fixe lors de la création du programme. Il s'applique aux variables globales, aux variables d'étendue de fichier et aux variables qualifiées avecstatic des fonctions internes définies.

L'allocation automatique de mémoire se produit pour les variables (non statiques) définies à l'intérieur des fonctions, et est généralement stockée sur la pile (bien que le standard C n'impose pas qu'une pile soit utilisée). Vous n'avez pas à réserver de mémoire supplémentaire pour les utiliser, mais d'un autre côté, vous avez également un contrôle limité sur la durée de vie de cette mémoire. Exemple: les variables automatiques dans une fonction ne sont là que jusqu'à la fin de la fonction.

void func() {
    int i; /* `i` only exists during `func` */
}

L'allocation de mémoire dynamique est un peu différente. Vous contrôlez maintenant la taille exacte et la durée de vie de ces emplacements mémoire. Si vous ne le libérez pas, vous rencontrerez des fuites de mémoire, ce qui peut entraîner le blocage de votre application, car à un moment donné, le système ne peut pas allouer plus de mémoire.

int* func() {
    int* mem = malloc(1024);
    return mem;
}

int* mem = func(); /* still accessible */

Dans l'exemple supérieur, la mémoire allouée est toujours valide et accessible, même si la fonction s'est terminée. Lorsque vous avez terminé avec la mémoire, vous devez la libérer:

free(mem);
Constantinius
la source
2
Bien sûr, vous avez le contrôle sur la durée de vie des variables ... c'est vous qui décidez de la portée, non?
Luchian Grigore
Bien sûr, mais ce n'est pas ce que je voulais dire. Vous ne pouvez pas prolonger la durée de vie des variables pour survivre à sa portée. Mais je devrais peut-être clarifier cela dans ma réponse. Merci
Constantinius
5
-1 Cette réponse est fausse. Vous confondez les variables statiques et automatiques .
brice
2
Votre propre phrase se lit comme suit: " L' allocation statique signifie que la mémoire pour vos variables est automatiquement allouée" C'est faux . Jetez un œil à ce que la page de manuel de la libc de GNU a à dire à ce sujet.
brice
1
@EliBendersky Il est reformulé maintenant. Vérifiez si c'est correct maintenant.
Suraj Jain
116

Ceci est une question d'entrevue standard:

Allocation de mémoire dynamique

La mémoire est-elle allouée au moment de l'exécution en utilisant calloc(), malloc()et friends. Elle est parfois également appelée mémoire de «tas», bien qu'elle n'ait rien à voir avec la structure de données du tas réf .

int * a = malloc(sizeof(int));

La mémoire du tas est persistante jusqu'à ce que free() soit appelée. En d'autres termes, vous contrôlez la durée de vie de la variable.

Allocation de mémoire automatique

C'est ce que l'on appelle communément la mémoire de «pile», qui est allouée lorsque vous entrez une nouvelle portée (généralement lorsqu'une nouvelle fonction est poussée sur la pile d'appels). Une fois que vous sortez de la portée, les valeurs des adresses de mémoire automatique ne sont pas définies et c'est une erreur d'y accéder .

int a = 43;

Notez que la portée ne signifie pas nécessairement la fonction. Les portées peuvent être imbriquées dans une fonction et la variable ne sera dans la portée que dans le bloc dans lequel elle a été déclarée. Notez également que l'endroit où cette mémoire est allouée n'est pas spécifié. (Sur un système sain d'esprit , ce sera sur la pile, ou dans les registres pour l'optimisation)

Allocation de mémoire statique

Est alloué au moment de la compilation * , et la durée de vie d'une variable en mémoire statique correspond à la durée de vie du programme .

En C, la mémoire statique peut être allouée à l'aide du staticmot - clé. La portée est uniquement l'unité de compilation.

Les choses deviennent plus intéressantes lorsque le externmot-clé est pris en compte . Lorsqu'une externvariable est définie, le compilateur lui alloue de la mémoire. Lorsqu'une externvariable est déclarée , le compilateur exige que la variable soit définie ailleurs. Le fait de ne pas déclarer / définir des externvariables causera des problèmes de liaison, tandis que l'échec de déclarer / définirstatic variables causera des problèmes de compilation.

dans la portée du fichier, le mot-clé static est facultatif (en dehors d'une fonction):

int a = 32;

Mais pas dans la portée de la fonction (à l'intérieur d'une fonction):

static int a = 32;

Techniquement, externet staticsont deux classes distinctes de variables en C.

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

* Notes sur l'allocation de mémoire statique

Il est quelque peu déroutant de dire que la mémoire statique est allouée au moment de la compilation, surtout si nous commençons à considérer que la machine de compilation et la machine hôte peuvent ne pas être identiques ou ne pas être sur la même architecture.

Il peut être préférable de penser que l'allocation de mémoire statique est gérée par le compilateur plutôt qu'allouée au moment de la compilation .

Par exemple, le compilateur peut créer une grande datasection dans le binaire compilé et lorsque le programme est chargé en mémoire, l'adresse dans ledatasegment du programme sera utilisé comme emplacement de la mémoire allouée. Cela présente l'inconvénient de rendre le binaire compilé très volumineux s'il utilise beaucoup de mémoire statique. Il est possible d'écrire un binaire de plusieurs gigaoctets généré à partir de moins d'une demi-douzaine de lignes de code. Une autre option est pour le compilateur d'injecter du code d'initialisation qui allouera de la mémoire d'une autre manière avant que le programme ne soit exécuté. Ce code variera en fonction de la plate-forme cible et du système d'exploitation. En pratique, les compilateurs modernes utilisent des heuristiques pour décider laquelle de ces options utiliser. Vous pouvez essayer cela vous-même en écrivant un petit programme C qui alloue un grand tableau statique d'éléments de 10k, 1m, 10m, 100m, 1G ou 10G. Pour de nombreux compilateurs, la taille binaire continuera de croître linéairement avec la taille du tableau, et au-delà d'un certain point,

Enregistrer la mémoire

La dernière classe de mémoire est constituée de variables «register». Comme prévu, les variables de registre doivent être allouées sur le registre d'un CPU, mais la décision est en fait laissée au compilateur. Vous ne pouvez pas transformer une variable de registre en référence en utilisant address-of.

register int meaning = 42;
printf("%p\n",&meaning); /* this is wrong and will fail at compile time. */

La plupart des compilateurs modernes sont plus intelligents que vous pour choisir les variables à mettre dans les registres :)

Références:

Brice
la source
3
Remarque: je suggérerais int * a = malloc(sizeof(*a));plutôt d'éviter de répéter le type de a. Cela rend les choses beaucoup plus faciles si jamais le type de achangements.
Shahbaz
1
En réalité, cela s'appelle tas mais cela n'a rien à voir avec la structure de données du tas. Heap dans ce cas signifie un endroit en désordre
dynamique
2
"Allocation de mémoire statique ... Est allouée au moment de la compilation" Voulez-vous dire que la taille d'allocation est déterminée au moment de la compilation? La mise de côté de la mémoire ne se produirait-elle pas uniquement au moment de l'exécution?
lf215 du
2

Allocation de mémoire statique: le compilateur alloue l'espace mémoire requis pour une variable déclarée.En utilisant l'adresse de l'opérateur, l'adresse réservée est obtenue et cette adresse peut être affectée à une variable pointeur.La plupart des variables déclarées ayant une mémoire statique, cette La manière d'attribuer une valeur de pointeur à une variable de pointeur est connue sous le nom d'allocation de mémoire statique. la mémoire est affectée pendant la compilation.

Allocation de mémoire dynamique: il utilise des fonctions telles que malloc () ou calloc () pour obtenir de la mémoire de manière dynamique.Si ces fonctions sont utilisées pour obtenir de la mémoire de manière dynamique et que les valeurs renvoyées par ces fonctions sont attribuées à des variables de pointeur, ces affectations sont appelées mémoire dynamique allocation.memory est assiné pendant l'exécution.

Rajeev Kumar
la source
2

Allocation de mémoire statique:

  • Les variables sont allouées de manière permanente
  • L'allocation se fait avant l'exécution du programme
  • Il utilise la structure de données appelée pile pour implémenter l'allocation statique
  • Moins efficace
  • Il n'y a pas de réutilisation de la mémoire

Allocation de mémoire dynamique:

  • Les variables ne sont allouées que si l'unité de programme devient active
  • L'allocation se fait pendant l'exécution du programme
  • Il utilise la structure de données appelée tas pour implémenter l'allocation dynamique
  • Plus efficace
  • Il existe une réutilisabilité de la mémoire . La mémoire peut être libérée lorsqu'elle n'est pas requise
vinay
la source
1
"Allocation de mémoire statique [...] Il utilise la structure de données appelée pile pour implémenter l'allocation statique" Non , c'est incorrect et trompeur. s'il vous plaît voir mon message pour la différence entre l'allocation automatique et statique. La mémoire statique peut utiliser la pile. Cela dépend fortement de la mise en œuvre et plusieurs stratégies peuvent être utilisées pour la même mise en œuvre. Je ne sais pas non plus ce que vous entendez par «moins efficace». @Trieu Toan, vous avez changé la signification de cette réponse avec une mauvaise modification.
brice
1

Différence entre l' allocation de mémoire statique et l' allocation dynamique de mémoire

La mémoire est allouée avant le début de l'exécution du programme (pendant la compilation).
La mémoire est allouée pendant l'exécution du programme.

Aucune action d'allocation de mémoire ou de désallocation n'est effectuée pendant l'exécution.
Les liaisons de mémoire sont établies et détruites pendant l'exécution.

Les variables restent allouées en permanence.
Attribué uniquement lorsque l'unité de programme est active.

Mis en œuvre à l'aide de piles et de tas.
Mis en œuvre à l'aide de segments de données.

Un pointeur est nécessaire pour accéder aux variables.
Pas besoin de pointeurs alloués dynamiquement.

Exécution plus rapide que Dynamic.
Exécution plus lente que statique.

Plus d'espace mémoire requis.
Moins d'espace mémoire requis.

Ebenezer
la source
1
l'allocation de mémoire statique est allouée sur la pile tandis que l'allocation de mémoire dynamique est allouée sur le tas
Usman Kurd
@UsmanKurd C'est généralement incorrect en ce qui concerne la mémoire statique. Voyez ma réponse.
brice
0

L'allocation de mémoire statique est allouée à la mémoire avant l'exécution du programme pf pendant la compilation. L'allocation de mémoire dynamique est une mémoire allouée pendant l'exécution du programme au moment de l'exécution.

Ritu maheswari
la source
-1

Allocation de mémoire statique. La mémoire allouée sera dans la pile.

int a[10];

Allocation de mémoire dynamique. La mémoire allouée sera dans le tas.

int *a = malloc(sizeof(int) * 10);

et ce dernier devrait être libre car il n'y a pas de Garbage Collector (GC) dans C.

free(a);
onemach
la source