Quando vengono allocati i vettori, usano la memoria nell'heap o nello stack?


151

Sono vere tutte le seguenti affermazioni?

vector<Type> vect; //allocates vect on stack and each of the Type (using std::allocator) also will be on the stack

vector<Type> *vect = new vector<Type>; //allocates vect on heap and each of the Type will be allocated on stack

vector<Type*> vect; //vect will be on stack and Type* will be on heap. 

Come viene allocata la memoria internamente Typein uno vectoro qualsiasi altro contenitore STL?


1
Possibile duplicato dei membri
underscore_d

Risposte:


222
vector<Type> vect;

alloca vector, ovvero le informazioni di intestazione, nello stack, ma gli elementi nel negozio gratuito ("heap").

vector<Type> *vect = new vector<Type>;

alloca tutto sul negozio gratuito.

vector<Type*> vect;

assegnerà lo vectorstack e un gruppo di puntatori nello store gratuito, ma dove questi punti sono determinati da come li usi (puoi dire l'elemento 0 allo store gratuito e l'elemento 1 allo stack, diciamo).


3
Ma sto avendo uno scenario, in cui sto ricevendo un errore di segmentazione quando Type sta diventando grande nella seconda dichiarazione. Supponevo che fosse perché il tipo veniva allocato nello stack.
Phelodas,

4
@Phelodas: senza vedere il tuo codice, questo è impossibile da valutare. Si prega di aprire una nuova domanda.
Fred Foo,

2
Circa vector<Type> vect;poiché gli elementi sono nell'heap e le informazioni di intestazione sono nello stack, quando le informazioni di intestazione vengono rimosse dalla memoria, come la funzione return, cosa accadrà alle memorie degli elementi? Vengono recuperati con le informazioni dell'intestazione o no? In caso contrario, ciò causerà una perdita di memoria?
flyrain,

3
@flyrain: i vettori ripuliscono dopo se stessi. Leggi su RAII .
Fred Foo,

1
@flyrain: dovrebbe funzionare. Si prega di inviare una nuova domanda con maggiori dettagli. Se pubblichi qui il link, potrei dargli un'occhiata.
Fred Foo,

25
vector<Type> vect; //allocates vect on stack and each of the Type (using std::allocator) also will be on the stack

No, vectsarà nello stack, ma l'array che utilizza internamente per archiviare gli oggetti sarà nell'heap. Gli articoli risiederanno in quell'array.

vector<Type> *vect = new vector<Type>; //allocates vect on heap and each of the Type will be allocated on stack

No. Come sopra, tranne per il fatto che la vectorclasse sarà anche nell'heap.

vector<Type*> vect; //vect will be on stack and Type* will be on heap. 

vectsarà nello stack, i suoi elementi (puntatori a Type) saranno nell'heap e non puoi dire dove saranno i Types cui puntano i puntatori. Potrebbe essere nello stack, potrebbe essere nell'heap, potrebbe essere nei dati globali, potrebbe non essere da nessuna parte (es. NULLPuntatori).

A proposito l'implementazione potrebbe infatti memorizzare alcuni vettori (in genere di piccole dimensioni) nello stack interamente. Non che io conosca tale implementazione, ma può farlo.


23

Supponendo un'implementazione che in realtà ha uno stack e un heap (lo standard C ++ non richiede di avere tali cose) l'unica vera affermazione è l'ultima.

vector<Type> vect;
//allocates vect on stack and each of the Type (using std::allocator) also will be on the stack

Questo è vero, tranne per l'ultima parte ( Typenon sarà nello stack). Immaginare:

  void foo(vector<Type>& vec) {
     // Can't be on stack - how would the stack "expand"
     // to make the extra space required between main and foo?
     vec.push_back(Type());
  }

  int main() {
    vector<Type> bar;
    foo(bar);
  }

Allo stesso modo:

 vector<Type> *vect = new vector<Type>; //allocates vect on heap and each of the Type will be allocated on stack

Vero tranne l'ultima parte, con un contro esempio simile:

  void foo(vector<Type> *vec) {
     // Can't be on stack - how would the stack "expand"
     // to make the extra space required between main and foo?
     vec->push_back(Type());
  }

  int main() {
    vector<Type> *bar = new vector<Type>;
    foo(bar);
  }

Per:

vector<Type*> vect; //vect will be on stack and Type* will be on heap. 

questo è vero, ma nota qui che i Type*puntatori saranno sull'heap, ma le Typeistanze che indicano non devono essere:

  int main() {
    vector<Type*> bar;
    Type foo;
    bar.push_back(&foo);
  }

in quale tipo di contesto non avresti uno stack? Capisco che stai dicendo che lo standard non lo richiede, ma praticamente parlando, quando saresti senza uno stack?
Nerdtron,

3
@Nerdtron - IIRC su alcuni piccoli microcontrollori hai uno stack di chiamate che può memorizzare nient'altro che il PC (contatore programmi) nel punto dell'ultima chiamata, pronto per un RET. Il compilatore potrebbe quindi scegliere di posizionare la "memorizzazione automatica" (per funzioni non ricorsive) in una posizione fissa con poca / nessuna relazione con il flusso di esecuzione. Potrebbe sensibilmente appiattire l'intero programma. Anche per il caso ricorsivo potresti avere una politica di "stack per funzione" o uno stack separato per variabili automatiche e indirizzi di ritorno, il che rende la frase "lo stack" piuttosto insignificante.
Flexo

È possibile utilizzare l'allocazione basata su heap per tutto e disporre di uno "stack di pulizia" che gestisca l'archiviazione automatica (e possibilmente deleteanche).
Flexo

3

Solo questa affermazione è vera:

vector <Type*> vect; //vect will be on stack and Type* will be on heap.

Type* i puntatori sono allocati sull'heap, poiché la quantità di puntatori può cambiare in modo dinamico.

vect in questo caso viene allocato nello stack, perché è stato definito come una variabile dello stack locale.


2
Tipo * non indica l'allocazione dell'heap, semplicemente un puntatore a un oggetto Type. Detto questo, il vettore memorizza il puntatore sull'heap. int a = 5; int * ptr_to_a = & a; vettore <int *> vec; vec.push_back (ptr_to_a); (vedi la risposta di jpalecek)
Matthew Russell,

1

il vettore ha un interno allocatorche si occupa di allocare / deallocare memorie da heapper vector element. Quindi, indipendentemente da come si crea un vettore, elementviene sempre allocato su heap. Per quanto riguarda i metadati del vettore, dipende dal modo in cui lo crei.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.