2017-03-08 35 views
4

我已經實現了一個功能,身份給我和我的控制。它返回std::shared_ptr<const void>。在函數中,我分配了任意數量的內存,並通過shared_ptr返回對它的訪問。正確的方式分配內存到std :: shared_ptr

我的存儲器分配是用new unsigned char[123]完成的。問題在於valgrind檢測到新變量和刪除變體的使用不匹配。雖然我使用new[](unsigned)來分配內存,但shared_ptr析構函數使用delete(void*)來釋放它,並且只要您使用「錯誤的」釋放器進行分配,valgrind就會發出警告。

在更實際的方面,我寫了這個測試案例來說明我的意思:

TEST(Example, Test1) 
{ 
    unsigned char* mem = new unsigned char[123]; 
    std::shared_ptr<const void> ptr(mem); 
} 

的Valgrind的報告說

==45794== Mismatched free()/delete/delete [] 
==45794== at 0x4C2A64B: operator delete(void*) (vg_replace_malloc.c:576) 
==45794== by 0x40B7B5: _M_release (shared_ptr_base.h:150) 
==45794== by 0x40B7B5: ~__shared_count (shared_ptr_base.h:659) 
==45794== by 0x40B7B5: ~__shared_ptr (shared_ptr_base.h:925) 
==45794== by 0x40B7B5: ~shared_ptr (shared_ptr.h:93) 
==45794== by 0x40B7B5: Example_Test1_Test::TestBody() (test.cc:108) 
==45794== Address 0x5cb6290 is 0 bytes inside a block of size 123 alloc'd 
==45794== at 0x4C29CAF: operator new[](unsigned long) (vg_replace_malloc.c:423) 
==45794== by 0x40B72E: Example_Test1_Test::TestBody() (test.cc:107) 

我想避免的valgrind過濾器如果可能的話。

什麼是正確的方式來分配任意數量的數據並返回std::shared_ptr<const void>

+0

用malloc分配怎麼樣? – Yury

+0

如果您使用'malloc'代替,則會得到類似的警告,因爲您沒有匹配'free'。 – Martin

回答

13

如果您給shared_ptr<T>指定一個T指針,它會假定您創建了一個對象,並暗示着刪除者delete p;。如果您的分配實際上是使用array-new進行的,那麼您需要通過一個適當的刪除程序來執行delete[] p;。如果你喜歡,你可以重複使用std::default_delete:(你甚至不需要外投,因爲轉換是隱含的)

return static_pointer_cast<const void>(
    std::shared_ptr<unsigned char>(
     new unsigned char[N], 
     std::default_delete<unsigned char[]>())); 

在C++ 17,shared_ptr支持數組,這樣你就可以說

shared_ptr<unsigned char[]>(new unsigned char[N]) 

那裏,並得到正確的刪除(然後轉換爲無效)。

+0

[Demo](http://melpon.org/wandbox/permlink/24Or4rgU851gtSYx),[modified demo](http://melpon.org/wandbox/permlink/tzFXH0NyKUPTht5E)。 –

+0

謝謝,像魅力一樣工作 – Martin

相關問題