Création d’object sur la stack / stack?

Le code suivant crée un object sur la stack:

Object o; 

Lors de la création d’un object 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’object en tas sur deux lignes et appelons le constructeur sur la deuxième ligne ( o = new object() ), cela signifie-t-il dans la première ligne ( Object* o ) que le pointeur a été créé sur la stack? So Object o place l’object sur la stack, alors que Object* o place le pointeur sur un futur object de la stack?

Ma deuxième question concerne si les deux lignes de code ont été appelées en dehors d’une classe. J’ai récemment lu ( gestion globale de la mémoire en C en stack ou en tas? ) Que les variables globales ne sont pas contenues dans la stack / stack mais en fait une autre partie de la mémoire? Si tel est le cas, Object* o créerait-il un pointeur qui serait placé dans cette autre partie de la mémoire et qui pointe vers l’object tas?

En fait, aucune des déclarations ne dit rien à propos du tas ou de la stack:

 Object o; 

crée un object avec stockage automatique , ce qui signifie que l’emplacement de stockage est déterminé par le contexte dans lequel l’object est déclaré: si le code est dans une fonction, il se trouve que c’est la stack 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 cela est différent:

 struct Foo { Object o; }; Foo* pf = new Foo(); 

Maintenant, l’object pf->o est créé sur le tas , pas sur la stack, même si (ou plutôt parce qu’il) dispose d’un stockage automatique.

Inversement,

 Object* p; 

déclare simplement un pointeur, rien de plus. Le stockage du pointeur ne se distingue pas de tout autre object: il dispose d’un stockage automatique. De plus, l’expression d’initialisation n’a aucun effet sur le stockage des variables.

Ce que le pointeur indique est une question complètement différente. Il peut s’agir d’un object alloué au tas (en utilisant new par exemple) ou il peut pointer vers un autre object alloué automatiquement. Considérer:

 Object o; Object* p = &o; 

C ++ propose trois manières différentes de créer des objects:

  1. Stack-based comme des objects temporaires
  2. Basé sur le tas en utilisant new
  3. Allocation de mémoire statique telle que les variables globales et les objects scope-namespace

Considérez votre cas,

 Object* o; o = new Object(); 

et:

 Object* o = new Object(); 

Les deux formes sont les mêmes. Cela signifie qu’une variable de pointeur o est créée sur la stack (supposez que vos variables n’appartiennent pas à la catégorie 3 ci-dessus) et pointe vers une mémoire dans le tas, qui contient l’object.

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

UNE)

 Object* o; o = new Object(); 

“ B)

 Object* o = new Object(); 

Je pense que A et B n’ont aucune différence. Dans les deux cas, o est un pointeur sur la classe Object. statement new Object () crée un object de classe Object à partir de la mémoire du tas. La déclaration d’affectation affecte l’adresse de la mémoire allouée au pointeur o.

Une chose que je voudrais mentionner, c’est que la taille de la mémoire allouée par le tas est toujours la taille (Object) et non la taille (Object) + la taille (void *).

Dans les deux exemples, des variables locales de type Object* sont allouées sur la stack. Le compilateur est libre de produire le même code à partir des deux extraits si votre programme ne détecte aucune différence.

La zone de mémoire pour les variables globales est la même que la zone de mémoire pour les variables statiques – ni sur la stack ni sur le tas. Vous pouvez placer des variables dans cette zone en les déclarant static dans la fonction. La conséquence est que l’instance est partagée entre des appels simultanés de votre fonction, vous devez donc considérer attentivement la synchronisation lorsque vous utilisez des statistiques.

Voici un lien vers une discussion de la disposition en mémoire d’un programme en cours d’exécution.