Quand la mémoire est-elle allouée aux variables locales en C

En tant que variables locales, elles sont également appelées variables automatiques et sont supposées se voir allouer de la mémoire au moment de l’exécution, lorsque la fonction est utilisée.

int main(){ int a; // declaration return 0; } int main(){ int a[]; // compilation error, array_size missing return 0; } int main(){ int a[2]; // declaration, but can't work without array_size, // so at comstack time it is checked! return 0; } 

Ma question est de savoir s’il ne s’agit que d’une règle donnant à array_size dans la déclaration en C, ou que la mémoire est allouée au moment de la compilation pour array (variable locale toujours)

Comment ça marche?

Un tableau est une variable selon la programmation C par K & R. pg no 161.

Lorsque vous déclarez une variable locale, sa taille est connue au moment de la compilation, mais une allocation de mémoire a lieu pendant le temps d’exécution.

Ainsi, dans vos exemples, un tableau sans taille est clairement un problème pour le compilateur, car il ne sait pas quelle est la taille à inclure dans le code assembleur.

Si vous ne connaissez pas la taille d’un tableau, vous pouvez toujours utiliser les types de pointeur et malloc / free ou même alloca . Les deux premiers fonctionnent sur le tas, et alloca utilise réellement la stack.

L’exception notable est les variables statiques. Leur stockage est déjà alloué à la compilation / liaison et ne peut pas être modifié à l’exécution.

Exemples:

 int main(int argc, const char *argv[]) { int a; // a is a sizeof(int) allocated on stack } int main(int argc, const char *argv[]) { int a[2]; // a is a sizeof(int)*2 allocated on stack } int main(int argc, const char *argv[]) { int *a; // a is a sizeof(int*) allocated on stack (pointer) a = alloca(sizeof(int)*4); // a points to an area with size of 4 integers // data is allocated on stack } int main(int argc, const char *argv[]) { static int a; // a is allocated in data segment, keeps the value } 
 int main(){ int a[2]; return 0; } 

Ici, int a[2]; est une définition d’une variable nommée a . a est un tableau de deux int .

En pratique, le compilateur émet du code pour utiliser de l’espace sur la stack pour 2 objects int adjacents (probablement 8 octets, mais la taille de int correspond à la mise en oeuvre). Cela suppose bien sûr que l’object n’est pas supprimé par l’optimiseur, car vous ne l’utilisez jamais.

L’erreur de compilation que vous avez eu pour int a[999999999]; est due à une limite ssortingcte imposée par le compilateur, car il sait (ou suppose de toute façon) qu’il n’y aura jamais assez de stack pour cela.

Comme indiqué par sgar91 dans les commentaires, un tableau comme dans votre exemple est alloué lors de l’appel d’une fonction et sa taille doit être déterminée. Si vous avez besoin de tableaux dynamics, vous devez allouer de la mémoire sur le tas.

 int *values = malloc(sizeof(int) * array_count); 

L’allocation automatique se produit lorsque vous déclarez une variable automatique, telle qu’un argument de fonction ou une variable locale . L’espace pour une variable automatique est alloué lorsque l’instruction composée contenant la déclaration est entrée et est libéré lors de la sortie de cette instruction composée.

C’est le point en C, où les tableaux et les pointeurs ne sont pas les mêmes.

Prenons cet exemple:

 int main(){ int a[5]; int * b = malloc(sizeof(int) * 5); printf("sizeof a = %d\n",sizeof a); printf("sizeof int[5] = %d\n",sizeof(int[5])); printf("sizeof b = %d\n",sizeof b); free(b); return 0; } 

Cela retournera:

 sizeof a = 20 sizeof int[5] = 20 sizeof b = 4 

La variable a est internal déclarée comme int [5], un pointeur d’entier pointant vers un bloc de mémoire avec un espace pour 5 entiers.

Pour les variables locales, la mémoire qu’elles consumnt se trouve sur la stack. Cela signifie qu’ils doivent avoir une taille fixe connue au moment de la compilation. Ainsi, lorsque la fonction est appelée, la quantité exacte de mémoire nécessaire est ajoutée à la stack en modifiant la valeur du pointeur de la stack. C’est pourquoi le tableau doit avoir une taille: le nombre d’octets sur la stack doit changer d’un montant fixe lors de l’appel de la fonction.

Les appels à malloc () et similaire allouent de la mémoire à partir du tas; La mémoire allouée de cette manière au moment de l’exécution peut être de taille variable.

Il existe une différence entre les variables locales et automatiques en C. Une variable locale peut être automatique ou statique , ce qui détermine si la mémoire correspondante est allouée sur la stack ou de manière permanente lors de la première exécution du programme.

Avec ce code:

 int main(){ int a[]; //compilation error, array_size missing return 0; } 

Ceci est un tableau incomplet . L’erreur est due au fait que le compilateur ne sait pas combien d’ int le programme devra allouer.

La taille du tableau doit être connue au moment de la compilation et vous pouvez passer directement au tableau ou indirectement, car la mémoire est définie au moment de la compilation mais allouée au moment de l’exécution, à l’exception du tableau de taille variable.