74 votes

Gestion globale de la mémoire en C++ : pile ou tas ?

Si je déclare une structure de données globalement dans une application C++, consomme-t-elle la mémoire de la pile ou du tas ?

Par exemple

struct AAA
{

.../.../.
../../..
}arr[59652323];

1 votes

Également, quelle est la différence entre une variable globale et une variable statique (au sein d'une fonction). Elles doivent vivre pendant toute la durée du programme...

0 votes

C'est vrai, mais il y a une différence entre l'accessibilité

0 votes

@dspinozzi : les constructeurs des variables globales sont appelés avant main(), mais les constructeurs des variables statiques sont appelés la première fois que la fonction est appelée. Les deux types de variables sont généralement stockés dans les mêmes parties de la mémoire - je pense que GCC les place dans la section .data.

140voto

Milan Points 5703

Puisque je n'étais pas satisfait des réponses, et que j'espère que le sameer karjatkar veut apprendre plus qu'une simple réponse oui/non, voici.

En général, un processus comporte 5 zones différentes de la mémoire allouée

  1. Code - segment de texte
  2. Données initialisées - segment de données
  3. Données non initialisées - segment bss
  4. Amas
  5. Pile

Si vous voulez vraiment savoir ce qui est sauvegardé et où, alors lisez et ajoutez ces pages à vos favoris :

COMPILATEUR, ASSEMBLEUR, ÉDITEUR DE LIENS ET CHARGEUR : UNE BRÈVE HISTOIRE (voir le tableau w.5)

Anatomie d'un programme en mémoire

alt text

0 votes

Cela signifie-t-il que les données non initialisées - bss et les données initialisées - font partie du tas ?

0 votes

Non, ils ne font pas partie du tas, ils sont dans des zones différentes comme il est écrit dans ma réponse (les 5 zones différentes). Le tas et la pile occupent la mémoire virtuelle au-dessus des segments de texte et de données.

8 votes

Le point important est que les segments bss et de données sont alloués lorsque le programme est chargé en mémoire pour la première fois, et que leur taille ne change pas pendant l'exécution du programme. En revanche, le contenu du tas est volatile et change tout au long de l'exécution, au fur et à mesure que des opérations de mémoire dynamique sont effectuées.

30voto

Charlie Martin Points 62306

Le problème ici est la question. Supposons que vous ayez un petit programme C(++ aussi, ils gèrent cela de la même manière) comme celui-ci :

/* my.c */

char * str = "Your dog has fleas.";  /* 1 */
char * buf0 ;                         /* 2 */

int main(){
    char * str2 = "Don't make fun of my dog." ;  /* 3 */
    static char * str3 = str;         /* 4 */
    char * buf1 ;                     /* 5 */
    buf0 = malloc(BUFSIZ);            /* 6 */
    buf1 = malloc(BUFSIZ);            /* 7 */

    return 0;
}
  1. Il n'est ni alloué sur la pile ni sur le tas. Au lieu de cela, il est alloué comme une donnée statique et placé dans son propre segment de mémoire sur la plupart des machines modernes. Les données réelles chaîne de caractères est également alloué en tant que données statiques et placé dans un segment en lecture seule dans les machines bien pensantes.
  2. est simplement un pointeur statique alloué ; de la place pour une adresse, dans des données statiques.
  3. a le pointeur alloué sur le pile et sera effectivement désalloué lorsque main retours. La chaîne, puisqu'il s'agit d'une constante, est allouée dans l'espace de données statiques avec les autres chaînes.
  4. est en fait alloué exactement comme au point 2. static Le mot-clé vous indique qu'il ne doit pas être alloué sur la pile.
  5. ...mais buf1 est sur la pile, et
  6. ... l'espace tampon mallocalisé est sur le tas.
  7. Et au fait, les enfants n'essayent pas ça à la maison. malloc a une valeur de retour intéressante ; vous devriez siempre vérifier la valeur de retour.

Par exemple :

char * bfr;
if((bfr = malloc(SIZE)) == NULL){
   /* malloc failed OMG */
   exit(-1);
}

0 votes

L'espace tampon malloqué n'a rien à voir avec les variables globales. Seuls les pointeurs sont globaux. S'il vous plaît pour ne pas confondre les gens plus loin.

10 votes

Oh, ne sois pas stupide. L'auteur de la question ne savait manifestement pas ce qui allait où, et j'ai donc rédigé une réponse visant à améliorer sa compréhension.

14voto

Tomek Kopczuk Points 1198

En général, il ne consomme ni l'un ni l'autre. Il essaie de les allouer dans un segment de mémoire qui est susceptible de rester de taille constante pendant l'exécution du programme. Il peut s'agir de bss, de pile, de tas ou de données.

0 votes

En éditant le fichier boot.ini, nous pouvons étendre la mémoire virtuelle à 3GB. Existe-t-il un paramètre pour le segment de mémoire ?

0 votes

Ce serait inutile, car la taille de la mémoire allouée statiquement ne peut jamais changer.

6voto

EFraim Points 7137

Ni l'un ni l'autre. C'est une section de données.

0 votes

Cela dépend si la mémoire globale a été allouée en ligne ou allouée dynamiquement à partir de l'application.

1 votes

Si une mémoire a été allouée dynamiquement, elle n'est pas globale (au sens de variable globale).

0 votes

Alors dans quel sens est-il global, s'il n'est pas dans le champ d'application de tout le programme ? !

5voto

Philippe Leybaert Points 62715

La mémoire globale est pré-allouée dans un bloc de mémoire fixe, ou sur le tas, selon la manière dont elle est allouée par votre application :

byte x[10]; // pre-allocated by the compiler in some fixed memory block
byte *y

main()
{
   y = malloc(10); // allocated on the heap
}

EDIT :

La question est confuse : Si j'alloue une structure de données globalement dans une application C++, consomme-t-elle la mémoire de la pile ou du tas ?

"allouer" ? Cela peut signifier beaucoup de choses, y compris appeler malloc(). Cela aurait été différent si la question était "si je déclare et initialise une structure de données de manière globale".

Il y a de nombreuses années, lorsque les processeurs utilisaient encore des segments de 64K, certains compilateurs étaient suffisamment intelligents pour allouer dynamiquement de la mémoire à partir du tas au lieu de réserver un bloc dans le segment .data (en raison des limitations de l'architecture mémoire).

Je suppose que je suis juste trop vieux....

0 votes

Il dit "alloué sur le tas" et c'est assez correct. A moins que cette question ne soit marquée "novice" ou "débutant", cela devrait être un rappel suffisant de ce qui se passe.

0 votes

@Don : Non. La chose globale est le pointeur, et non la mémoire vers laquelle il pointe. Vous pouvez gérer la mémoire comme vous le souhaitez. Elle n'est pas non plus là pour rester pendant toute l'exécution. Vous pouvez même parfois la faire pointer vers la pile.

1 votes

S'il y a une leçon à en tirer, c'est que vous devez éviter de répondre à des questions dont le sens exact n'est pas clair. Ma réponse n'est pas fausse, c'est juste que certaines personnes pensent que leur interprétation d'un mot est suffisante pour rejeter tout ce qui ne va pas dans leur sens. Même maintenant, 10 heures après que la question ait été posée, le sens de la question n'est toujours pas clair.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X