web-dev-qa-db-fra.com

Où en mémoire mes variables sont-elles stockées dans C?

En considérant que la mémoire est divisée en quatre segments: données, tas, pile et code, d'où proviennent les variables globales, les variables statiques, les types de données constants, les variables locales (définies et déclarées dans des fonctions), les variables (dans la fonction principale), les pointeurs , et les espaces alloués dynamiquement (avec malloc et calloc) sont-ils stockés en mémoire?

Je pense qu'ils seraient alloués comme suit:

  • Variables globales -------> données
  • Variables statiques -------> data
  • Types de données constants -----> code
  • Variables locales (déclarées et définies dans des fonctions) --------> pile
  • Variables déclarées et définies dans la fonction principale -----> tas
  • Pointeurs (par exemple, char *arr, int *arr) -------> tas
  • Espace alloué dynamiquement (en utilisant malloc et calloc) --------> pile

Je ne parle de ces variables que du point de vue de C.

S'il vous plaît corrigez-moi si je me trompe car je suis nouveau en C.

127
starkk92

Vous en avez bien compris, mais celui qui a écrit les questions vous a dupé sur au moins une question:

  • variables globales -------> data (correct)
  • variables statiques -------> data (correct)
  • types de données constants -----> code et/ou données. Envisagez des littéraux de chaîne pour une situation dans laquelle une constante elle-même serait stockée dans le segment de données et où des références à celle-ci seraient incorporées dans le code.
  • variables locales (déclarées et définies dans des fonctions) --------> pile (correcte)
  • variables déclarées et définies dans main fonction -----> tas empiler aussi (le professeur essayait de vous duper)
  • pointeurs (ex: char *arr, int *arr) -------> tas données ou pile, selon le contexte. C vous permet de déclarer un pointeur global ou static, auquel cas le pointeur lui-même se retrouverait dans le segment de données.
  • espace alloué dynamiquement (en utilisant malloc, calloc, realloc) --------> empiler tas

Il est à noter que "pile" est officiellement appelé "classe de stockage automatique".

183
dasblinkenlight

Pour les futurs visiteurs susceptibles d'être intéressés par ces segments de mémoire, j'écris des points importants sur 5 segments de mémoire en C:

Quelques heads-up:

  1. Chaque fois qu'un programme C est exécuté, de la mémoire est allouée dans la RAM pour son exécution. Cette mémoire est utilisée pour stocker le code fréquemment exécuté (données binaires), les variables de programme, etc. Les segments de mémoire ci-dessous parlent de la même chose:
  2. Il existe généralement trois types de variables:
    • Variables locales (également appelées variables automatiques en C)
    • Variables globales
    • Variables statiques
    • Vous pouvez avoir des variables statiques globales ou statiques locales, mais les trois ci-dessus sont les types parents.

5 segments de mémoire en C:

1. Segment de code

  • Le segment de code, également appelé segment de texte, est la zone de mémoire contenant le code fréquemment exécuté.
  • Le segment de code est souvent en lecture seule pour éviter le risque d'être écrasé par des problèmes de programmation tels que le dépassement de mémoire tampon, etc.
  • Le segment de code ne contient pas de variables de programme telles que variable locale (, également appelées variables automatiques dans C ), variables globales, etc.
  • Sur la base de l'implémentation C, le segment de code peut également contenir des littéraux de chaîne en lecture seule. Par exemple, lorsque vous faites printf("Hello, world"), la chaîne "Hello, world" est créée dans le segment code/texte. Vous pouvez le vérifier à l'aide de la commande size sous Linux.
  • Lectures complémentaires

Segment de données

Le segment de données est divisé en deux parties et se situe généralement sous la zone de tas ou dans certaines mises en œuvre au-dessus de la pile, mais le segment de données ne se trouve jamais entre la zone de tas et celle de la pile.

2. Segment de données non initialisé

  • Ce segment est également appelé bss .
  • C'est la partie de la mémoire qui contient:
    1. Variables globales non initialisées (y compris les variables de pointeur)
    2. Variables globales constantes non initialisées .
    3. Variables statiques locales non initialisées .
  • Toute variable locale globale ou statique non initialisée sera stockée dans le segment de données non initialisé.
  • Par exemple: la variable globale int globalVar; ou la variable locale statique static int localStatic; sera stockée dans le segment de données non initialisé.
  • Si vous déclarez une variable globale et l'initialisez sous le nom 0 ou NULL, le segment de données non initialisé ou le fichier bss le serait quand même.
  • Lectures complémentaires

3. Segment de données initialisé

  • Ce segment stocke:
    1. Variables globales initialisées (y compris les variables de pointeur)
    2. Variables globales constantes initialisées .
    3. Variables statiques locales initialisées .
  • Par exemple: la variable globale int globalVar = 1; ou la variable locale statique static int localStatic = 1; sera stockée dans un segment de données initialisé.
  • Ce segment peut être ultérieurement classé en zone de lecture seule initialisée et en zone de lecture-écriture initialisée . Les variables globales constantes initialisées iront dans la zone de lecture seule initialisée, tandis que les variables dont les valeurs peuvent être modifiées à l'exécution iront dans la zone de lecture-écriture initialisée .
  • La taille de ce segment est déterminée par la taille des valeurs du code source du programme et ne change pas au moment de l'exécution .
  • Lectures complémentaires

4. Segment de pile

  • Le segment de pile est utilisé pour stocker les variables créées dans les fonctions (, fonction pouvant être la fonction principale ou définie par l'utilisateur ), variable telle que
    1. Variables locales de la fonction (y compris les variables de pointeur)
    2. Arguments passés à function
    3. Adresse de retour
  • Les variables stockées dans la pile seront supprimées dès que l'exécution de la fonction sera terminée.
  • Lectures complémentaires

5. segment de tas

  • Ce segment doit prendre en charge l'allocation de mémoire dynamique. Si le programmeur veut allouer de la mémoire dynamiquement, alors en C c'est fait en utilisant les méthodes malloc, calloc ou realloc.
  • Par exemple, lorsque int* prt = malloc(sizeof(int) * 2), huit octets sont alloués dans le segment de mémoire et l'adresse de mémoire de cet emplacement est renvoyée et stockée dans la variable ptr. La variable ptr sera soit sur la pile, soit sur le segment de données, en fonction de la façon dont elle est déclarée/utilisée.
  • Lectures complémentaires
102
hagrawal

Correction de vos mauvaises phrases

constant data types ----->  code //wrong

variables constantes locales -----> pile

variable constante globale initialisée -----> segment de données

variable constante globale non initialisée -----> bss

variables declared and defined in main function  ----->  heap //wrong

variables déclarées et définies dans la fonction principale -----> pile

pointers(ex:char *arr,int *arr) ------->  heap //wrong

dynamically allocated space(using malloc,calloc) --------> stack //wrong

pointeurs (ex: char * arr, int * arr) -------> la taille de cette variable de pointeur sera dans la pile.

Considérez que vous allouez une mémoire de n octets (en utilisant malloc ou calloc) de manière dynamique, puis en faisant une variable de pointeur pour la pointer. Maintenant que n octets de mémoire sont en tas et que la variable de pointeur requiert 4 octets (si 8 octets machine 64 bits) qui seront en pile pour stocker le pointeur de départ du n octets de bloc de mémoire.

Remarque: Les variables de pointeur peuvent pointer la mémoire de tout segment.

int x = 10;
void func()
{
int a = 0;
int *p = &a: //Now its pointing the memory of stack
int *p2 = &x; //Now its pointing the memory of data segment
chat *name = "ashok" //Now its pointing the constant string literal 
                     //which is actually present in text segment.
char *name2 = malloc(10); //Now its pointing memory in heap
...
}

espace alloué dynamiquement (à l'aide de malloc, calloc) --------> tas

8
rashok

Une architecture de bureau populaire divise la mémoire virtuelle d'un processus en plusieurs segments:

  • Segment de texte: contient le code exécutable. Le pointeur d'instruction prend des valeurs dans cette plage.

  • Segment de données: contient des variables globales (c'est-à-dire des objets avec une liaison statique). Subdivisé en données en lecture seule (telles que les constantes de chaîne) et en données non initialisées ("BSS").

  • Segment de pile: contient la mémoire dynamique du programme, c’est-à-dire le magasin libre ("heap") et les cadres de pile locaux pour tous les threads. Traditionnellement, la pile C et le tas C se développaient dans le segment de la pile à partir d'extrémités opposées, mais je pense que cette pratique a été abandonnée car elle est trop dangereuse.

Un programme C place généralement des objets de durée de stockage statique dans le segment de données, des objets alloués dynamiquement sur le magasin libre et des objets automatiques sur la pile d'appels du thread dans lequel il réside.

Sur d’autres plates-formes, telles que l’ancien mode réel x86 ou sur des périphériques intégrés, les choses peuvent évidemment être radicalement différentes.

6
Kerrek SB

Je ne fais référence à ces variables que de la perspective C.

Du point de vue du langage C, tout ce qui compte est l’ampleur, la portée, les liens et l’accès; La façon dont les éléments sont mappés sur différents segments de mémoire dépend de l'implémentation individuelle, et cela varie. Le langage standard ne parle pas de segments de mémoire du tout. La plupart des architectures modernes agissent principalement de la même manière; les variables de bloc et les arguments de fonction seront attribués à partir de la pile, les variables de fichier et statiques seront attribués à partir d'un segment de données ou de code, la mémoire dynamique sera allouée à partir d'un segment de mémoire, certaines données constantes seront stockées dans des segments en lecture seule. , etc.

5
John Bode
  • Variables/variables automatiques ---> section de pile
  • Variables allouées dynamiquement ---> section de tas
  • Variables globales initialisées -> section de données
  • Variables globales non initialisées -> section de données (bss)
  • Variables statiques -> section de données
  • Constantes de chaîne -> section de texte/section de code
  • Fonctions -> section de texte/section de code
  • Code texte -> section de texte/section de code
  • Registres -> Registres CPU
  • Entrées de ligne de commande -> section environnement/ligne de commande
  • Variables d'environnement -> section environnement/ligne de commande
1
prashad

pointeurs (ex: char * arr, int * arr) -------> tas

Non, ils peuvent être sur la pile ou dans le segment de données. Ils peuvent pointer n'importe où.

1
Steve Wellens

Une chose à ne pas oublier concernant le stockage est la règle comme si . Le compilateur n'est pas obligé de placer une variable à un endroit spécifique. Il peut la placer où bon lui semble aussi longtemps que le programme compilé se comporte comme si c'était un programme exécuté la machine C abstraite selon ses règles. Ceci s’applique à tout le stockage durées . Par exemple:

  • une variable qui n'est pas accessible à tous peut être éliminée complètement - elle n'a pas de mémoire ... nulle part. Exemple - voyez comment il y a 42 dans le code d'assemblage généré mais aucun signe de 404.
  • une variable à durée de stockage automatique dont l'adresse n'a pas été prise n'a pas besoin d'être stockée en mémoire. n exemple serait une variable de boucle.
  • une variable qui est const ou effectivement const n'a pas besoin d'être en mémoire. Exemple - le compilateur peut prouver que foo est effectivement const et en inclut l'utilisation dans le code. bar a une liaison externe et le compilateur ne peut pas prouver qu'il ne serait pas changé en dehors du module actuel, il n'est donc pas en ligne.
  • un objet affecté de malloc n'a pas besoin de résider dans la mémoire allouée à partir du tas! Exemple - remarquez que le code n'a pas d'appel à malloc et que la valeur 42 n'est jamais stockée en mémoire, elle est conservée dans un registre!
  • ainsi, un objet qui a été alloué par malloc et la référence est perdue sans le désallocation de l'objet avec free pas besoin de fuite de mémoire ...
  • l'objet alloué par malloc n'a pas besoin d'être dans le tas ci-dessous l'interruption du programme (sbrk(0)) sous Unixen ...
0
Antti Haapala