2013-10-16 19 views
7

güvenliVector.emplace_back'i kullanmak için güvenli (yeni MyPointer); Vektör içindeki arıza sızdıran belleğe neden olabilir mi?

vector.emplace_back(new MyPointer()); 

Veya bir istisna atılır olabilir veya vektör nedeni bellek sızıntısı içindeki bazı başarısızlık kullanımı var mı?

Aşağıdakilerden bazılarını yapmak için işaretçiyi geçici bir unique_ptr içine yerleştirmek daha iyi olur mu?

vector.emplace_back(std::unique_ptr<MyPointer>(new MyPointer())); 

Eğer bir vektör arızası meydana gelirse, geçici unique_ptr hala belleği temizleyecektir?

+0

Std :: make_unique' adlı bir C++ 14 desteğinin kullanılabilir olduğunu veya bulunmadığını varsayalım. – chris

cevap

11

güvenli değil ve ilk sürümü kullanıyorsanız bir bellek sızıntısı oluşturur. documentation, bir istisna atılırsa, emplace numaralı aramanın hiçbir etkisinin olmadığını belirtir - yani, ilettiğiniz düz işaretçi hiçbir zaman silinmez. C++ 14 henüz mevcut değilse

sadece make_unique kendi versiyonunu rulo, sen

vector.emplace_back(std::make_unique<MyPointer>()); 

kullanabilirsiniz

vector.emplace_back(std::unique_ptr<MyPointer>(new MyPointer())); 

veya C++ 14 ile kullanmak ya da yükselebilir. here'u bulabilirsiniz.

+3

Ayrıca, yukarıdaki "vektör" türünü de değiştirmeniz gerekir. Bu mümkün değilse, eklenmiş öğeyi akıllı bir işaretçide saklayabilir, ekleyebilir, ardından çalışıp çalışmadığını belirtebilirsiniz. – Yakk

+0

'C++ 14' yerine 'C++ 11' mi demek istiyorsunuz? – fnc12

+2

@ fnc12 Hayır, C++ 14 demek istedim. ['std :: make_unique'] (http://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique) C++ 11’de standart/standartlaştırılamadı. –

2

Hayır, ilk senaryo güvenli değil ve vector bir istisna atarsa ​​belleği sızdırmaz. std::unique_ptr<T>T*T*T*T* olarak dönüştürülemez, ikinci senaryo derlenmeyecektir. Olabilse bile, bu senaryo ilkinden daha kötüdür, çünkü işaretleyiciyi vektörünüze ekleyecektir, sonra işaret edilen nesneyi hemen siler. Sarkan bir işaretçi içeren bir vektör ile bırakılacaksınız.

std::vector türünüzün türünü değiştirmeden (bunun std::vector<MyPointer*> olduğunu varsayalım) bu kod istisnasını güvenli hale getirmenin iki yolu vardır. Kullanılması

C++ 11:

auto ptr = std::unique_ptr<MyPointer>(new MyPointer()); 
vector.emplace_back(ptr.get()); 
ptr.release(); 

Veya daha ayrıntılı C++ 03 yolu:

MyPointer* ptr = new MyPointer(); 
try 
{ 
    vector.push_back(ptr); 
} 
catch (...) 
{ 
    delete ptr; 
    throw; 
} 

sonra olan en kolay yöntem sizin std::vector<MyPointer*> türünü değiştirmek mümkün değilse

std::vector<std::unique_ptr<MyPointer>> vector; 
vector.emplace_back(std::unique_ptr<MyPointer>(new MyPointer())); 

Veya C++ 14 ile: yukarıda Daniel Frey tarafından teklif edilenler

std::vector<std::unique_ptr<MyPointer>> vector; 
vector.emplace_back(std::make_unique<MyPointer>()); 
İlgili konular