Question

Dans le contexte de C ++ (pas que cela compte):

class Foo{
    private:
        int x[100];
    public:
        Foo();
}

Ce que j'ai appris me dit que si vous créez une instance de Foo comme ceci:

Foo bar = new Foo();

Ensuite, le tableau x est alloué sur le tas, mais si vous avez créé une instance de Foo comme ceci:

Foo bar;

Ensuite, il est créé sur la pile.

Je ne trouve pas de ressources en ligne pour le confirmer.

Était-ce utile?

La solution

Avec une légère modification de votre exemple:

class Foo{
    private:
        int x[100];
        int *y;
    public:
        Foo()
        {
           y = new int[100];
        }
        ~Foo()
        { 
           delete[] y; 
        }

}

Exemple 1:

Foo *bar = new Foo();
  • x et y sont sur le tas:
  • sizeof (Foo *) est créé sur la pile.
  • sizeof (int) * 100 * 2 + sizeof (int *) est sur le tas

Exemple 2:

Foo bar;
  • x est sur la pile et y est sur le tas
  • sizeof (int) * 100 est sur la pile (x) + sizeof (int *)
  • sizeof (int) * 100 est sur le tas (y)

Les tailles réelles peuvent différer légèrement en raison de l'alignement classe / structure en fonction de votre compilateur et de votre plate-forme.

Autres conseils

À proprement parler, il n’est pas nécessaire que l’objet existe sur une pile ou un tas. La norme définit 3 types de «durée de stockage», mais n'indique pas exactement comment le stockage doit être mis en œuvre:

  1. durée de stockage statique
  2. durée de stockage automatique
  3. durée de stockage dynamique

La durée de stockage automatique est généralement (presque toujours) mise en œuvre à l'aide de la pile.

La durée de stockage dynamique est généralement mise en œuvre à l'aide du segment de mémoire (finalement via malloc () ), bien que cela puisse être remplacé même par l'utilisateur du compilateur.

La durée de stockage statique est ce qu'on appelle généralement des globals (ou stockage statique).

La norme dit ceci à propos de ces choses (les extraits suivants sont des extraits de 3.7 - Durée de stockage):

  

Durée de stockage statique et automatique   sont associés aux objets introduits   par des déclarations (3.1) et implicitement   créé par l'implémentation (12.2).   La durée de stockage dynamique est   associé à des objets créés avec   nouvel opérateur (5.3.4).

     

...

     

Tous les objets non dynamiques   durée de stockage, ni local ont   durée de stockage statique. Le stockage   pour ces objets doivent durer pour la   durée du programme (3.6.2,   3.6.3).

     

...

     

Objets locaux explicitement déclarés auto   ou s'inscrire ou pas explicitement déclaré   statique ou externe ont automatique   durée de stockage. Le stockage pour   ces objets dure jusqu'à ce que le bloc   où ils sont créés, sort.

     

...

     

Les objets peuvent être créés dynamiquement   pendant l'exécution du programme (1.9), en utilisant   new-expressions (5.3.4), et détruit   utiliser delete-expressions (5.3.5). Un c   L’implémentation ++ permet d’accéder au stockage dynamique et de le gérer via   les fonctions d'allocation globale   nouvel opérateur et nouvel opérateur [] et   les fonctions de désallocation globale   opérateur delete et opérateur delete [].

     

...

     

La bibliothèque fournit les valeurs par défaut   définitions pour l'allocation globale   et fonctions de désallocation. Certains   allocation globale et désallocation   les fonctions sont remplaçables (18.4.1)

Et enfin (en ce qui concerne le tableau dans votre exemple de classe):

  

3.7.4 Durée des sous-objets [basic.stc.inherit]

     

La durée de stockage des sous-objets membres, des sous-objets de la classe de base et des éléments de tableau est celle de leur   objet (1.8).

Un objet de type Foo prend la taille de 100 ints stockés en séquence. Si vous le créez sur la pile, vous aurez tout sur la pile. Si vous le faites avec new, ce sera sur le tas en tant que partie de l'objet.

Cela fait partie de la spécification du langage, je ne suis pas sûr de votre question.

Oui, le tableau de membres x sera créé sur le segment de mémoire si vous créez l'objet Foo sur le segment de mémoire. Lorsque vous allouez de la mémoire dynamique à Foo , vous demandez une mémoire de longueur sizeof (Foo) (plus éventuellement une surcharge de mémoire, mais ignorons-le pour le moment), qui dans votre exemple de code implique une taille de 100 int . Ceci doit tenir compte de la durée de vie des objets de type Foo (et de leurs données internes) pour couvrir plusieurs domaines.

Si vous ne créez pas l'objet Foo sur le segment de mémoire et que le tableau interne de Foo n'est pas un pointeur auquel vous allouez de la mémoire avec new dans le constructeur de Foo , ce tableau interne sera créé sur la pile. Là encore, cela doit être le cas pour que le tableau soit automatiquement nettoyé sans aucun delete à la fin de la portée. Plus précisément,

struct Foo {
    int* y;
    Foo() : y(new int()) { }
    ~Foo() { delete y; }
};

créera y sur le tas, qu'un objet Foo ait été créé sur la pile ou sur le tas.

Vous voulez dire

Foo* bar = new Foo(); 

Je suppose. Ce est créé dans le tas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top