Ketika vektor dialokasikan, apakah mereka menggunakan memori pada heap atau stack?


151

Apakah semua pernyataan berikut ini benar?

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. 

Bagaimana memori dialokasikan secara internal Typedalam vectorwadah STL atau lainnya?


Jawaban:


222
vector<Type> vect;

akan mengalokasikan vector, yaitu info header, di stack, tetapi elemen-elemen di toko gratis ("heap").

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

mengalokasikan semuanya di toko gratis.

vector<Type*> vect;

akan mengalokasikan vectorpada stack dan banyak pointer di toko gratis, tetapi di mana titik ini ditentukan oleh bagaimana Anda menggunakannya (Anda bisa mengarahkan elemen 0 ke toko gratis dan elemen 1 ke stack, katakanlah).


3
Tetapi saya memiliki skenario, di mana saya mendapatkan kesalahan segmentasi ketika Type tumbuh besar pada deklarasi kedua. Saya berasumsi bahwa itu karena Type dialokasikan pada stack.
Phelodas

4
@Phelodas: tanpa melihat kode Anda, ini tidak mungkin dinilai. Silakan buka pertanyaan baru.
Fred Foo

2
Tentang vector<Type> vect;karena elemen ada di heap dan info header ada di stack, ketika info header dihapus dari memori, seperti fungsi kembali, apa yang akan terjadi pada memori elemen? Apakah mereka direklamasi dengan info tajuk atau tidak? Jika tidak, apakah ini akan menyebabkan memori bocor?
flyrain

3
@flyrain: vektor membersihkan diri mereka sendiri. Baca di RAII .
Fred Foo

1
@flyrain: itu seharusnya berhasil. Silakan kirim pertanyaan baru dengan lebih detail. Jika Anda memposting tautan di sini, saya mungkin melihatnya.
Fred Foo

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

Tidak, vectakan ada di stack, tetapi array yang digunakan secara internal untuk menyimpan item akan ada di heap. Item akan berada di array itu.

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

Tidak. Sama seperti di atas, kecuali vectorkelas akan berada di heap juga.

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

vectakan berada di tumpukan, itemnya (pointer ke Type) akan berada di heap, dan Anda tidak bisa tahu di mana akan menjadi Typetitik pointer ke. Bisa di stack, bisa di heap, bisa di data global, bisa di mana saja (mis.NULL Pointer).

BTW implementasi sebenarnya bisa menyimpan beberapa vektor (biasanya berukuran kecil) pada stack sepenuhnya. Bukan berarti saya tahu implementasi seperti itu, tetapi bisa.


23

Dengan asumsi implementasi yang sebenarnya memiliki tumpukan dan tumpukan (standar C ++ tidak membuat persyaratan untuk memiliki hal-hal seperti itu) satu-satunya pernyataan yang benar adalah yang terakhir.

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

Ini benar, kecuali untuk bagian terakhir ( Typetidak akan ada di tumpukan). Membayangkan:

  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);
  }

Juga:

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

Benar kecuali bagian terakhir, dengan contoh penghitung serupa:

  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);
  }

Untuk:

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

ini benar, tetapi perhatikan di sini bahwa Type*pointer akan berada di tumpukan, tetapi Typecontoh yang mereka tunjukkan tidak perlu:

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

dalam konteks apa Anda tidak memiliki setumpuk? Saya mengerti Anda mengatakan standar tidak memerlukannya, tetapi secara praktis, kapan Anda tanpa tumpukan?
Nerdtron

3
@Nerdtron - IIRC pada beberapa mikrokontroler kecil Anda memiliki tumpukan panggilan yang dapat menyimpan tidak lain dari PC (penghitung program) pada titik panggilan terakhir, siap untuk RET. Oleh karena itu kompiler Anda mungkin memilih untuk menempatkan "penyimpanan otomatis" (untuk fungsi non-rekursif) di lokasi tetap dengan sedikit / tidak ada hubungannya dengan aliran eksekusi. Itu cukup masuk akal bisa meratakan seluruh program. Bahkan untuk kasus rekursif Anda dapat memiliki kebijakan "tumpukan per fungsi" atau tumpukan terpisah untuk variabel otomatis dan mengembalikan alamat, yang membuat frasa "tumpukan" agak tidak berarti.
Flexo

Anda dapat menggunakan alokasi berbasis tumpukan untuk semuanya dan memiliki "tumpukan pembersihan" yang mengelola penyimpanan otomatis (dan mungkin deletejuga).
Flexo

3

Hanya pernyataan ini yang benar:

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

Type* pointer dialokasikan pada heap, karena jumlah pointer dapat berubah secara dinamis.

vect dalam hal ini dialokasikan pada stack, karena Anda mendefinisikannya sebagai variabel stack lokal.


2
Ketik * tidak menunjukkan alokasi tumpukan, hanya penunjuk ke objek Jenis. Yang mengatakan, vektor tidak menyimpan pointer di heap. int a = 5; int * ptr_to_a = & a; vektor <int *> vec; vec.push_back (ptr_to_a); (lihat jawaban jpalecek)
Matthew Russell

1

vektor memiliki internal allocatoryang bertugas mengalokasikan / membatalkan alokasi memori dari heapuntuk vector element. Jadi, tidak masalah bagaimana Anda membuat vektor, elementselalu dialokasikan pada heap. Adapun metadata vektor, itu tergantung pada cara Anda membuatnya.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.