2013-10-12 12 views
13

Paylaşılan işaretçileri tutan vector.clear() öğesini çağırdıktan sonra, shared_ptr tarafından sahip olunan nesnenin yıkıcılarının serbest bırakılmayacağını fark ettim.Paylaşılan işaretçiler vektörü, vektör temizlendikten sonra bellek sorunları

Kod örneği aşağıda görülebilir. Vector.clear() çağrılırken bile, paylaşılan işaretçiden sonra adı geçen yıkıcı, kapsamın ötesine geçer. Benim sorum onları sıfırlamak suretiyle vektör içindeki tüm akıllı işaretçileri silmek zorunda mıyım? Tavsiye edebileceğiniz daha kolay bir yolu var mı?

Output : 

constructor 
I am here 
destructor 

Code: 

#include <vector> 
#include <iostream> 
#include <memory> 

using namespace std; 

class A 
{ 
public: 
    A(){cout << "constructor" << endl;}; 
    ~A(){cout << "destructor" << endl;}; 
}; 

int main() 
{ 
    shared_ptr<A> sharedptr (new A); 
    std::vector<shared_ptr<A> > test; 
    test.push_back(sharedptr); 

    test.clear(); 
    cout << "I am here" << endl; 
} 

cevap

23

Bu durumda shared_ptr<A> iki kopyası, bir sharedptr değişken ve vektör bir öğe olarak başka bir şeydir.

yerine bu

test.push_back(std::move(sharedptr)); 

not do artık orijinal sharedptr iç taşındı ve artık kullanılamaz var sahiptir. Diğer bir şey, hiçbir şey yapmamaktır, bu paylaşılan_ptr ve sharedptr mükemmel geçerli bir kullanım kapsamı bittikten sonra kendini temizleyecektir.

+0

Cevabınız sadece aradığım şey. Çok teşekkürler. –

+0

Soruda gösterilen durumda bunu eklemeliyim ki, kullanım sırasında tehlikeli olabilecek kullanımı kolay bir değişken ('sharedptr') kullanmaktan kaçınmak için, vektörü vektörte 'emplace_back' ile oluşturmayı tercih ederim. 'std :: move'. – us2012

4

Sorun, push_back öğesinin, paylaşılan ana sayfanın kopyasını kopyasına eklediğinde, ana orijinale kadar ana sarkmayı kaldırarak ortaya çıkar. Shared_ptr'yi ana kapsamda yapmazsanız, sorun olmaz. Sadece shared_ptr'yi ana kapsamda yapmaktan kaçının. Push_back çağrısında geçici bir hak olarak yapın. İşte

Output is now: 

constructor 
I am almost there 
destructor 
I am here 

New code: 

#include <vector> 
#include <iostream> 
#include <memory> 

using namespace std; 

class A 
{ 
public: 
    A(){cout << "constructor" << endl;}; 
    ~A(){cout << "destructor" << endl;}; 
}; 

int main() 
{ 
    vector<shared_ptr<A> > test; 
    test.push_back(shared_ptr<A>(new A)); 
    cout << "I am almost there" << endl; 
    test.clear(); 
    cout << "I am here" << endl; 
    return 0; 
} 
+0

maked_shared veya emplace_back hakkında ne düşünüyorsunuz? – GameDeveloper

2

sharedptr ve vektör payı sadece bir kez yapıcı ve yıkıcı çağrılırken sonuçlanacaktır aynı nesne öğesi.