Soru C ++ vektör :: temizle


vector <weight> decoy;

void clear_decoy() {  

    decoy.clear();   

    vector<weight> (decoy).swap(decoy);  
}

Yukarıdaki yöntemde clear_decoy(), nedir vector<weight> (decoy).swap(decoy);  lütfen demek?

Yöntem açık mı decoy ya da değil? Teşekkürler!


22
2017-08-13 14:19


Menşei


Onay işaretini tıklayarak en iyi olduğunu düşündüğünüz cevapları kabul etmeyi unutmayın. - Nick T


Cevaplar:


Yeni bir vektör oluşturur Weight nesneler (boş olacak) ve ile değiştirir decoy.

Bunun nedeni, varsayılan olarak, std::vector<t>::clear Genellikle bir vektör tarafından kullanılan depolama alanını azaltmaz, sadece orada bulunan tüm nesneleri yok eder. Bu şekilde, vektör, gelecekte yeniden tahsis edilmeksizin daha fazla nesne saklamak için alana sahiptir.

Ancak bazen, vektördeki kapasiteyi kırpmak istersiniz. Yeni oluşturulmuş bir vektörle (bu satırın sonuna kadar yaşadığı ve bu nedenle orada yok edildiği) değiş tokuş etmek, vektör tarafından tahsis edilen tüm belleği serbest bırakır.


20
2017-08-13 14:22



Ah hayatım! Sevgilim C ++, seni bizden daha akıllı olarak sevenler için sorun yaratıyorsun. - Agnel Kurian
Zeki olmak sosyal bir maliyete sahiptir. - Klaim
Bu çok C ++ y. C ++ bellek yönetimini burada sunar, böylece ihtiyaçlarınız için şeyleri kişiselleştirme şansınız olur. Varsayılan olarak C ++, olabildiğince hızlı olmaya çalışır ve bu kodu izlemezseniz daha hızlı kod alırsınız. Çok büyük bir vektörünüzün olduğu ve öğelerinizin çoğunu kaldırdığınız durumlarda, bu deyimi, işletim giderlerini işletim sisteminden serbest bırakmak için kullanabilirsiniz. Genellikle bunu yapmak istemezsiniz (yani, bozuk olmayanları düzeltmeyin). - wilhelmtell


Bu formu daha önce hiç görmedim.

Bunu şöyle yazdım:

vector<weight>().swap(decoy);

Bu, "yeni bir boş vektör oluştur ve mevcut olanla değiştir" anlamına gelir.

vector<weight> (decoy).swap(decoy);

Bunu anlamak için parçalara ayırın.

vector<weight>(decoy)  yeni bir vektör yarat (buradaki içerikler, şu anda boş bir dekonden kopyalanır). Yeni vektör, bir anonim geçicidir, bu yüzden isminin bu olduğunu söyleyelim newvector.

newVector.swap(decoy);  yeni vektörü decopy ile değiştirir.

(Hataları düzeltmek için yorum başına güncellendi)


22
2017-08-13 14:23



Aynı şeyden daha iyi (ve daha) ortak bir yapı önermek için +1. - Billy ONeal
Bu olmalı vector<weight>().swap(decoy). Temsillerde üye işlevlerini çağırabilirsiniz, ancak bunları yerleşik olmayan referans argümanları olarak iletemezsiniz. - Mike Seymour
+1 Kötü bir tipçiyim. :) - John Dibling
Bence C ++ 0x STL tanımı bir shrink bellek ayak izini gerçek boyuta göre azaltmak için ... ya da bu arzulu düşünce mi? - Matthieu M.
@Matthieu: evet, buna denir shrink_to_fitama uygulama onurlandırmak zorunda değil. - Mike Seymour


Bu kod, vektörün tahsis ettiği belleğin serbest kalmasını sağlamak için ortak bir hile kullanma girişimi başarısız. Vektörün kopya kurucusunun belleği, diğer vektörün boyutuna veya kapasitesine uyup uymayacağına bağlı olarak, aslında bunu yapabilir veya gerçekleştirmeyebilir.

Belleği güvenilir şekilde boşaltmak için aşağıdakileri kullanın:

void clear_decoy() {  
    vector<weight>().swap(decoy);  
}

Bu geçici bir boş vektör oluşturur (az veya hiç bellek ayrılmamış), decoy böylece hafıza şimdi geçici olarak sahip olunur, sonra geçici olanı ortadan kaldırır, hafızayı serbest bırakır.


10
2017-08-13 14:31



Mükemmel nokta. - John Dibling
Bu doğru olsa da, burada aklına dayalı hiçbir STL uygulaması tahsis edilmeyecektir. - Billy ONeal
@ Billy: Gerçekten de; Clumsy net-kopya-takas dansı çalışması büyük olasılıkla, ancak daha basit sürümü çalışmak için garanti edilir. - Mike Seymour


clear tüm girişleri vektörden kaldırır, ancak alanı boşaltamaz. Bu takas deyimi, vektörü hiçbir boş alana sahip olmayacak şekilde geri yükler.


6
2017-08-13 14:21



Aslında clear  kutu Vektörün kapladığı alanı tahsis eder. Ama öyle değil var için. Genellikle çoğu STL uygulamasında yoktur. - Billy ONeal
@Billy ONeal: Teşekkürler. Cevabımı düzenledim. - Fred Larson


0A0D'nin de belirttiği gibi, swap iki vektör arasındaki altta yatan kontrollü belleği değiştirmektir. Ama bu biraz daha fazla açıklama gerektiriyor.

Sen ne zaman clear bir vectorÖğeler, en azından programcı söz konusu olduğunda, bundan çıkarılır. size() sıfır olur ve capacity() değişebilir veya değişmeyebilir. Ancak Standart, vektör tarafından kullanılan belleğin aslında işletim sistemine geri gönderileceğini garanti etmez. Yani, vektörde önce 1000 elemanın olsaydı clear() ve her biri 1000 bayt bellek aldıktan sonra clear() Her elemanın yıkıcısı denir, ancak vektör hala 1.000.000 baytlık bir dağıtımda tutuyor olabilir.

Bu bazen istenmeyen bir durumdur. Yukarıda not ettiğiniz 'takas numarası', iki vektör arasındaki kontrollü hafızayı değiştirmenin etkisine sahiptir. bundan dolayı decoy kontrollü bellek sıfırlama ile biter.

İşte adım adım neler oluyor:

  1. decoy öğelerin her biri erased. Elemanların yıkıcılar denir ve vektörler size() sıfır olur. Gerçek hafıza ayrılmamak.
  2. Yığın üzerine yeni bir vektör oluşturulur (vector<weight> (decoy)) ve decoy ona kopyalanır. Dan beri decoy sadece clear()ed, geçici vektöre hiçbir öğe kopyalanmaz. Bununla birlikte, aşağıdaki düzenlemeye bakın. Kontrollü belleğin değiştirilmediğini bilmiyorsunuz.
  3. Geçici vektörler ve decoyhafızası değişti (.swap(decoy);) sonuçlanan decoy hem temizlendi hem de hafıza geçici olarak transfer edildi.
  4. Geçici, yığından ayrılır ve hafızanın tahsis edilmesiyle sonuçlanır.

Bu "olarak anılırtakas numarası".

DÜZENLEME: Mike'ın da belirttiği gibi, orijinal programcı yanlış yapıyor. Geçici geçici olarak yapılmamalıdır. decoyvarsayılan olarak yapılandırılmalıdır. Bundan emin değilsin. swap() Altında sadece kontrol edilen hafızayı değil, öğeleri kopyalayacaktır.


3
2017-08-13 14:32



+1 Harika açıklama


Açık,

Vektörün tüm elemanları   düştü: onların yıkıcıları denir,   ve daha sonra   vektör konteyner, bırakarak   0 büyüklüğünde konteyner.

Takas sadece iki vektörü değiştirir,

İçeriği değiştir

Vektörün içeriğini değiştirir   başka bir vec içeriği   aynı türden vektör. Boyutları olabilir   farklılık.

Bu üyeye yapılan çağrıdan sonra   fonksiyon, buradaki öğeler   konteyner vec içinde olanlar   aramadan önce ve   vec bu olanlar vardı. Herşey   yineleyiciler, referanslar ve işaretçiler   değiştirilen vektörler için geçerli kalır.

Görünüşe göre gerçekten hiçbir şey değişmiyor ve sadece varsayılan ayırmaya geri yükleniyor. Clear tahliye edebilir ama bazen yapamaz. Yalnızca boyutunu küçültmekle kalmaz, ayrıca swap deyimiyle ayrılan alanı da azaltırsınız.


1
2017-08-13 14:20



bellek serbest bırakıldı mı? - ladyfafa
@ladyfafa: Takas beyanı ile tahsis edilen alanın miktarı azalır. Bu, vektörlerin güzel bir parçası.
Teşekkürler görüyorum!! - ladyfafa