Vektörler ayrıldığında, yığın veya yığın üzerinde bellek kullanıyorlar mı?


151

Aşağıdaki ifadelerin tümü doğru mu?

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. 

Nasıl bellek için dahili olarak tahsis edilir Typebir yer vectorya da başka bir STL konteyner?


Yanıtlar:


222
vector<Type> vect;

vectorbaşlık bilgisini yani yığın bilgisini yığına tahsis eder , ancak serbest depodaki öğeleri ("öbek") tahsis eder .

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

her şeyi ücretsiz mağazaya tahsis eder.

vector<Type*> vect;

tahsis edecek vectoryığını ve ücretsiz mağaza işaretçiler oluşan bir demet, ancak bu nokta bunları kullanmak nasıl belirlenir nerede (eğer yığını ücretsiz mağazası ve eleman 1'e elemanı 0 eder misiniz derler).


3
Ancak, Type ikinci bildirimde büyüdüğünde bir segmentasyon hatası aldığım bir senaryo yaşıyorum. Tür yığını üzerinde tahsis edildi çünkü olduğunu varsayıyordum.
Phelodas

4
@Phelodas: Kodunuzu görmeden bunu değerlendirmek imkansız. Lütfen yeni bir soru açın.
Fred Foo

2
Hakkında vector<Type> vect;unsurlar öbek üzerinde ve başlık bilgileri başlık bilgisi fonksiyon dönüşü gibi, bellekten kaldırılır yığının üzerinde olduğu için hangi öğeleri anılar ne olacak? Üstbilgi bilgisi ile geri kazanılmış mı, değil mi? Değilse, bu bellek sızıntısına neden olur mu?
flyrain

3
@flyrain: vektörler kendilerinden sonra temizlenir. RAII'de okuyun .
Fred Foo

1
@flyrain: bu işe yaramalı. Lütfen daha fazla ayrıntı içeren yeni bir soru gönderin. Bağlantıyı buraya gönderirseniz, ona bir göz atabilirim.
Fred Foo

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

Hayır, vectyığın üzerinde olacak, ancak öğeleri depolamak için dahili olarak kullandığı dizi öbek üzerinde olacak. Öğeler bu dizide yer alacaktır.

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

Hayır. Sınıfla aynı vectorşekilde, yığın da olacaktır.

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

vectyığını üzerinde olacak, öğeleri (işaretçileri Type) yığın üzerinde olacak Typeve işaretçilerin işaret ettiği noktaların nerede olacağını söyleyemezsiniz . Yığın üzerinde olabilir, yığın üzerinde olabilir, küresel verilerde olabilir, hiçbir yerde (yani NULLişaretçiler) olabilir.

BTW uygulaması aslında bazı vektörleri (tipik olarak küçük boyutlu) yığına tamamen depolayabilir. Böyle bir uygulamayı bildiğimden değil, ama yapabilir.


23

Aslında bir yığın ve bir yığın (standart C ++ böyle şeylere sahip olma zorunluluğu yoktur) bir uygulama varsayarsak, tek doğru ifade sonuncusu.

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

Bu son kısım hariç doğrudur ( Typeyığın üzerinde olmayacak). Hayal etmek:

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

Aynı şekilde:

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

Benzer bir sayaç örneği ile son bölüm hariç doğrudur:

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

İçin:

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

bu doğrudur, ancak burada Type*işaretçilerin yığın üzerinde olacağını, ancak Typeişaret etmeleri gereken örneklerin olmayacağını unutmayın:

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

ne tür bir bağlamda yığınınız olmazdı? Standardın gerektirmediğini söylüyorsunuz, ama pratik olarak, ne zaman yığınsız olacaksınız?
Nerdtron

3
@Nerdtron - IIRC bazı küçük mikrodenetleyicilerde, son çağrı noktasında bir RET için hazır olan PC'den (program sayacı) başka hiçbir şey depolayamayan bir çağrı yığını var. Bu nedenle derleyiciniz "otomatik depolama" işlevini (özyinelemesiz işlevler için) yürütme akışıyla çok az ilişkisi olan / hiç ilişkisi olmayan sabit bir konuma yerleştirmeyi seçebilir. Tüm programı oldukça makul bir şekilde düzleştirebilir. Özyinelemeli durumda bile, "işlev başına yığın" ilkesine veya otomatik değişkenler ve dönüş adresleri için ayrı bir yığına sahip olabilirsiniz, bu da "yığın" ifadesini bir şekilde anlamsız hale getirir.
Flekso

Sen için esaslı tahsisini yığın kullanabilir şeyi ve (muhtemelen ve otomatik depolama yöneten bir "temizleme yığını" var deleteçok).
Flekso

3

Yalnızca bu ifade doğrudur:

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

Type* işaretçiler yığın üzerinde ayrılır, çünkü işaretçilerin miktarı dinamik olarak değişebilir.

vect bu durumda yerel bir yığın değişkeni olarak tanımladığınız için yığına ayrılır.


2
Type *, yığın tahsisini belirtmez, sadece Type nesnesine bir işaretçi olur. Bununla birlikte, vektör işaretçiyi yığın üzerinde saklar. int a = 5; int * ptr_to_a = & a; vektör <int *> vec; vec.push_back (ptr_to_a); (bkz. jpalecek'in cevabı)
Matthew Russell

1

Vektör, bir iç var allocator/ ayırmalarına anılar ayırmayı kaldırma sorumlu olan heapiçin vector element. Yani nasıl bir vektör oluşturursanız olun element, her zaman heap. Vektörün meta verilerine gelince, onu oluşturma şeklinize bağlıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.