Création d'un objet sur la pile/tas?

le code suivant crée un objet sur la pile:

Object o;

lors de la création d'un objet sur le tas nous pouvons utiliser:

Object* o;

o = new Object();

plutôt que:

Object* o = new Object();

lorsque nous divisons la création d'objet tas en deux lignes et appelons le constructeur sur la deuxième ligne ( o = new object() ), cela signifie-t-il que dans la première ligne ( Object* o ) le pointeur a été créé sur la pile? Donc Object o met l'objet sur le stack, alors que Object* o place le pointeur vers un futur objet sur la pile?

ma deuxième question concerne si les deux lignes de code ont été appelées en dehors d'une classe. J'ai lu récemment ( Mondial de la gestion de la mémoire en C dans la pile ou le tas? ) que les variables globales ne sont pas contenues sur la pile / tas mais une autre partie de la mémoire? Si c'est le cas, serait Object* o créer un pointeur qui serait assis dans cette autre partie de la mémoire et il pointer vers l'objet heap?

39
demandé sur Community 2012-04-15 00:31:47

5 réponses

en fait, aucune des deux déclarations ne dit quoi que ce soit sur le tas ou la pile:

Object o;

crée un objet avec stockage automatique ce qui signifie que l'emplacement de stockage est déterminé par le contexte dans lequel l'objet est déclaré: Si le code est dans une fonction, cela se trouve être la pile d'appels. Mais la ligne peut aussi être un membre de classe ou, comme vous l'avez noté, en dehors d'une fonction / Classe.

pour illustrer pourquoi ceci est différent:

struct Foo {
    Object o;
};

Foo* pf = new Foo();

maintenant l'objet pf->o est créé sur le tas , pas sur la pile, même si (ou plutôt, parce que ) il a un stockage automatique.

à L'inverse,

Object* p;

déclare simplement un pointeur, rien de plus. Le pointeur ’s de stockage est indistinguible de tout autre objet: il a un stockage automatique. En outre, l' l'initialisation de l'expression n'a aucun effet sur le stockage variable.

ce que le pointeur indique est une question complètement différente. Il peut s'agir d'un objet attribué en tas (en utilisant new par exemple) ou d'un autre objet attribué automatiquement. Prendre en considération:

Object o;
Object* p = &o;
78
répondu Konrad Rudolph 2012-04-15 12:45:45

C++ offre trois façons différentes de créer des objets:

  1. de Pile, tels que les objets temporaires
  2. basé sur le Tas à l'aide de nouvelle
  3. attribution de mémoire statique telle que variables globales et objets namespace-scope

considérez votre cas,

Object* o;
o = new Object();

et:

Object* o = new Object();

les deux formes sont de même. Cela signifie qu'une variable pointeur o est créée sur la pile (supposons que vos variables n'appartiennent pas à la catégorie 3 ci-dessus) et qu'elle pointe vers une mémoire dans le tas, qui contient l'objet.

9
répondu DML 2014-11-06 10:11:06

les deux formes sont identiques à une exception près: temporairement, la nouvelle (Object *) a une valeur non définie lorsque la création et la cession sont séparées. Le compilateur peut les combiner ensemble, depuis l'indéfini pointeur n'est pas particulièrement utile. Cela ne concerne pas les variables globales (sauf si la déclaration est globale, auquel cas c'est toujours vrai pour les deux formes).

3
répondu geekosaur 2012-04-14 20:36:44

A)

Object* o;
o = new Object();

` B)

Object* o = new Object();

je pense que A et B n'ont pas de différence. Dans les deux cas, o est un pointeur vers un objet de classe. déclaration new Object () crée un objet d'objet de classe à partir de la mémoire heap. L'instruction Assignment assigne l'adresse de la mémoire allouée au pointeur O.

une chose que je voudrais mentionner que la taille de la mémoire allouée de tas est toujours la taille (objet) pas sizeof (objet) + sizeof (void *).

2
répondu user966379 2012-04-15 12:59:54

dans vos deux exemples, les variables locales de type Object* sont attribuées sur la pile. Le compilateur est libre de produire le même code à partir des deux extraits s'il n'y a aucun moyen pour votre programme de détecter une différence.

la zone mémoire pour les variables globales est la même que la zone mémoire pour les variables statiques - elle n'est ni sur la pile ni sur le tas. Vous pouvez placer des variables dans cette zone en les déclarant static à l'intérieur de la fonction. La conséquence de ce faisant, l'instance devient partagée parmi les invocations simultanées de votre fonction, vous devez donc considérer soigneusement la synchronisation lorsque vous utilisez la statique.

Ici est un lien pour une discussion de la disposition de la mémoire de l'exécution d'un programme C.

1
répondu dasblinkenlight 2012-04-14 20:42:29