allocation de mémoire dans Stack and Heap

Cela peut sembler une question très fondamentale, mais cela m’a été dans ma tête:

Lorsque nous allouons une variable locale, elle entre dans la stack. De la même manière, l’allocation dynamic entraîne le passage de la variable sur le tas. Ma question est la suivante: cette variable est-elle réellement sur une stack ou sur un tas, ou bien nous allons simplement faire référence à la stack et à Heap

Par exemple,

Supposons que je déclare une variable int i . Maintenant, ce i est alloué sur la stack. Donc, quand j’imprimer l’adresse de i , ce sera l’un de l’emplacement sur la stack? Même question pour le tas aussi.

Je ne suis pas tout à fait sûr de ce que vous demandez, mais je ferai de mon mieux pour vous répondre.

Ce qui suit déclare une variable i sur la stack:

 int i; 

Lorsque je demande une adresse à l’aide de &i j’obtiens l’emplacement réel sur la stack.

Lorsque j’alloue quelque chose de manière dynamic à l’aide de malloc , deux données sont en cours de stockage. La mémoire dynamic est allouée sur le tas et le pointeur lui-même est alloué sur la stack. Donc dans ce code:

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

Cela alloue de l’espace sur le tas pour un entier. C’est également allouer de l’espace sur la stack pour un pointeur ( j ). La valeur de la variable j est définie sur l’adresse renvoyée par malloc .

Espérons que ce qui suit est utile:

 void foo() { // an integer stored on the stack int a_stack_integer; // a pointer to integer data, the pointer itself is stored on the stack int *a_stack_pointer; // make a_stack_pointer "point" to integer data that's allocated on the heap a_stack_pointer = (int*)malloc(10 * sizeof(int)); } 

Dans le cas de variables de stack, la variable elle-même (les données réelles) est stockée dans la stack.

Dans le cas de la mémoire allouée au segment de mémoire, les données sous-jacentes sont toujours stockées sur le segment de mémoire. Un pointeur sur cette mémoire / ces données peut être stocké localement sur la stack.

J’espère que cela t’aides.

La variable de pointeur elle-même résiderait sur la stack. La mémoire indiquée par le pointeur réside sur le tas.

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

i résiderais sur la stack, la mémoire réelle sur laquelle je pointe *i serais sur le tas.

Je suis d’accord avec Chris. Juste une autre façon d’expliquer cela. Considérons le code suivant:

 int* j = malloc(sizeof(int)); free(j); 

Même après avoir utilisé free (j), qui devrait libérer la mémoire du tas, le pointeur existe toujours et nous devons explicitement le rendre NULL. Ceci suggère clairement qu’il existe également une contrepartie de stack du pointeur, sinon il aurait dû être inexistant après la commande free. Cette variable de stack est celle qui pointe vers l’adresse du tas où la mémoire a été allouée dynamicment à l’aide de malloc.

stack ou tas ne sont pas des mémoires séparées, ce sont des segments de mémoire auxquels un programme en cours est alloué par le système, mais différentes façons d’organiser les données en mémoire.

Ainsi, lorsque vous obtenez & i, il s’agit d’une adresse mémoire, aussi simple que cela.

La réponse de M. Eberle est correcte à 100%, mais comme Google l’a indiqué comme première réponse lors de la recherche d’un malloc heap or stack , je dois append que malloc() alloue des données sur le tas le plus au monde. Si les données allouées étaient supérieures à MMAP_THRESHOLD qui est généralement de 128 Ko sur les systèmes 32 bits, malloc() n’utilisera pas le tas et allouera les données dans un segment de mémoire anonyme situé généralement sous la stack, augmentant dans le sens de la faible mémoire.

C’est la même région que celle où se trouvent les bibliothèques chargées dynamicment ( libc.so , etc.). Voici le passage pertinent de l’ man malloc :

Normalement, malloc () alloue de la mémoire à partir du tas et ajuste la taille du tas selon les besoins, à l’aide de sbrk (2). Lors de l’allocation de blocs de mémoire plus grands que MMAP_THRESHOLD octets, l’implémentation glibc malloc () alloue la mémoire en tant que mappage anonyme privé à l’aide de mmap (2). MMAP_THRESHOLD est de 128 Ko par défaut, mais il est ajustable avec mallopt (3). Avant Linux 4.7, les allocations effectuées à l’aide de mmap (2) n’étaient pas affectées par la limite de ressources RLIMIT_DATA; depuis Linux 4.7, cette limite est également appliquée pour les allocations effectuées à l’aide de mmap (2).

Comme exemple pratique, n’hésitez pas à consulter le post suivant . Il alloue essentiellement 300 Ko avec malloc() , puis exécute pmap pour afficher le segment de mémoire approprié.