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:
char *arr
, int *arr
) -------> tasJe 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.
Vous en avez bien compris, mais celui qui a écrit les questions vous a dupé sur au moins une question:
main
fonction -----> char *arr
, int *arr
) -------> static
, auquel cas le pointeur lui-même se retrouverait dans le segment de données.malloc
, calloc
, realloc
) --------> Il est à noter que "pile" est officiellement appelé "classe de stockage automatique".
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:
5 segments de mémoire en C:
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.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.
int globalVar;
ou la variable locale statique static int localStatic;
sera stockée dans le segment de données non initialisé.0
ou NULL
, le segment de données non initialisé ou le fichier bss le serait quand même.int globalVar = 1;
ou la variable locale statique static int localStatic = 1;
sera stockée dans un segment de données initialisé.malloc
, calloc
ou realloc
.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.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
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.
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.
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ù.
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:
42
dans le code d'assemblage généré mais aucun signe de 404
.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.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!malloc
et la référence est perdue sans le désallocation de l'objet avec free
pas besoin de fuite de mémoire ...malloc
n'a pas besoin d'être dans le tas ci-dessous l'interruption du programme (sbrk(0)
) sous Unixen ...