2014-05-15 147 views
3

我有一個對象,顯然是雙刪除,儘管是由智能指針跟蹤。我對使用智能指針很陌生,所以我做了一個簡單的函數來測試我是否正確使用對象。共享指針雙刪除

int *a = new int(2); 

std::shared_ptr<int> b(a); 
std::shared_ptr<int> c(a); 

主函數中的這組行導致運行時錯誤,因爲指針超出範圍,爲什麼?智能指針是否應該能夠自己處理刪除操作?

+1

你對自己刪除?你不應該那樣做。使用make_shared而不是手動分配一個。 – Kiroxas

回答

0

正確的用法是:

std::shared_ptr<int> b = std::make_shared<int>(2); 
std::shared_ptr<int> c = b; 
9

一個shared_ptr預計自己所指向的對象。

你所做的事是創建獨立的智能指針,每一個認爲它有潛在的int的獨佔所有權。他們不知道彼此的存在,他們不相互交談。因此,當它們超出範圍時,兩個指針都會刪除底層資源,並帶來明顯的結果。

當您創建shared_ptr時,它會創建一種「管理對象」,它負責資源的生命週期。當您複製 a shared_ptr時,兩個副本引用相同的管理對象。管理對象會跟蹤多少個shared_ptr實例指向此資源。一個int*本身沒有這樣的「管理對象」,因此複製它不會跟蹤引用。

這是你的代碼的最小改寫:

// incidentally, "make_shared" is the best way to do this, but I'll leave your 
// original code intact for now. 
int *a = new int(2); 

std::shared_ptr<int> b(a); 
std::shared_ptr<int> c = b; 

現在,他們都引用相同的底層管理對象。由於每個shared_ptr被銷燬,因此int*上的引用數量會減少,並且最後一個引用也會被刪除。

+0

更好的風格是做std :: shared_ptr b(new int(2))來避免有一個過渡指針a。意味着a)被範圍內的一些隨機代碼刪除的危險; b)在達到shared_ptr之前發生異常時發生內存泄漏。 shared_ptr被設計爲能夠從構造函數中獲取原始指針,這就是它的原因。更好的方法是,std :: shared_ptr b(std :: make_shared ) - make_shared只有一個內存分配,而以前的方式至少有兩個內存分配。 – h9uest

+0

@ h9uest如果這不是對原始問題中提供的代碼的最小修改,那麼您的觀點會更加相關。它從來沒有打算成爲C++的完美例子,也從未聲稱過。如果你閱讀代碼塊中的註釋,你會發現提到了'make_shared'。 – Rook

2

您只允許從原始指針創建一個智能指針。所有其他共享指針必須是第一個的副本才能正常工作。更妙的是:使用化妝共享:

std::shared_ptr<int> sp1 = std::make_shared<int>(2); 
std::shared_ptr<int> sp2 = sp1; 

編輯:忘了添加第二個指針