Domanda

Nel contesto di C ++ (non è importante):

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

Quello che ho imparato mi dice che se crei un'istanza di Foo in questo modo:

Foo bar = new Foo();

Quindi l'array x viene allocato sull'heap, ma se hai creato un'istanza di Foo in questo modo:

Foo bar;

Quindi viene creato nello stack.

Non riesco a trovare risorse online per confermarlo.

È stato utile?

Soluzione

Data una leggera modifica del tuo esempio:

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

}

Esempio 1:

Foo *bar = new Foo();
  • xey sono nell'heap:
  • sizeof (Foo *) viene creato nello stack.
  • sizeof (int) * 100 * 2 + sizeof (int *) è nell'heap

Esempio 2:

Foo bar;
  • x è nello stack e y è nell'heap
  • sizeof (int) * 100 è nello stack (x) + sizeof (int *)
  • sizeof (int) * 100 è nell'heap (y)

Le dimensioni effettive possono differire leggermente a causa dell'allineamento di classe / struttura a seconda del compilatore e della piattaforma.

Altri suggerimenti

A rigor di termini, secondo lo standard, l'oggetto non deve necessariamente esistere su una pila o un mucchio. Lo standard definisce 3 tipi di "durata della memoria", ma non specifica esattamente come deve essere implementata la memoria:

  1. durata dell'archiviazione statica
  2. durata della memorizzazione automatica
  3. durata della memoria dinamica

La durata della memorizzazione automatica è in genere (quasi sempre) implementata utilizzando lo stack.

La durata della memorizzazione dinamica viene in genere implementata utilizzando l'heap (in definitiva tramite malloc () ), sebbene ciò possa essere sovrascritto anche dall'utente del compilatore.

La durata dell'archiviazione statica è ciò che è comunemente noto come globale (o archiviazione statica).

Lo standard ha questo da dire su queste cose (i seguenti sono estratti da vari bit di 3.7 - Durata della memorizzazione):

  

Durata di archiviazione statica e automatica   sono associati agli oggetti introdotti   dalle dichiarazioni (3.1) e implicitamente   creato dall'implementazione (12.2).   La durata della memoria dinamica è   associato ad oggetti creati con   operatore nuovo (5.3.4).

     

...

     

Tutti gli oggetti che non hanno nessuno dinamico   durata di conservazione né locale   durata dell'archiviazione statica. Lo stoccaggio   per questi oggetti deve durare per il   durata del programma (3.6.2,   3.6.3).

     

...

     

Gli oggetti locali dichiarati esplicitamente auto   o registrati o non esplicitamente dichiarato   statico o esterno hanno automatico   durata di conservazione. Lo spazio di archiviazione per   questi oggetti durano fino al blocco   da cui vengono creati esce.

     

...

     

Gli oggetti possono essere creati dinamicamente   durante l'esecuzione del programma (1.9), usando   nuove espressioni (5.3.4) e distrutte   usando delete-expressions (5.3.5). CORRENTE ALTERNATA   + + l'implementazione fornisce l'accesso e la gestione dell'archiviazione dinamica tramite   le funzioni di allocazione globale   operatore nuovo e operatore nuovo [] e   le funzioni di deallocazione globale   operator delete e operator delete [].

     

...

     

La libreria fornisce l'impostazione predefinita   definizioni per l'allocazione globale   e funzioni di deallocazione. Alcuni   allocazione globale e deallocazione   le funzioni sono sostituibili (18.4.1)

E infine (per quanto riguarda l'array nella tua classe di esempio):

  

3.7.4 Durata degli oggetti secondari [basic.stc.inherit]

     

La durata di archiviazione degli oggetti secondari, degli oggetti secondari della classe base e degli elementi dell'array è quella del loro completo   oggetto (1.8).

Un oggetto di tipo Foo prende la dimensione di 100 in memorizzata in sequenza. Se lo crei nello stack, otterrai tutto nello stack. Se lo fai con nuovi, sarà sull'heap come parte dell'oggetto.

Fa parte delle specifiche del linguaggio, non sono sicuro di quale sia la tua domanda.

Sì, l'array membro x verrà creato sull'heap se si crea l'oggetto Foo sull'heap. Quando si alloca memoria dinamica per Foo si richiede memoria di lunghezza sizeof (Foo) (più eventualmente un sovraccarico di memoria, ma per il momento ignorarlo), che per il momento) nel tuo codice di esempio implica la dimensione di 100 int s. Questo deve essere valido per la durata della vita di oggetti di tipo Foo (e relativi dati interni) per attraversare gli ambiti.

Se non si crea l'oggetto Foo sull'heap e l'array interno di Foo non è un puntatore a cui si alloca memoria con nuovo nel costruttore di Foo , allora quell'array interno verrà creato nello stack. Ancora una volta, questo deve essere il caso affinché l'array venga pulito automaticamente senza delete s al termine dell'ambito. In particolare,

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

creerà y sull'heap indipendentemente dal fatto che un oggetto Foo sia stato creato sullo stack o sull'heap.

Intendi

Foo* bar = new Foo(); 

Suppongo. Quello viene creato nell'heap.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top