Correct way to allocate memory to std::shared_ptr

巧了我就是萌 提交于 2020-01-14 13:10:40

问题


I have implemented a function where the identity is given to me and out of my control. It returns std::shared_ptr<const void>. In the function i allocate an arbitrary amount of memory, and return access to it though the shared_ptr.

My memory allocation is done with new unsigned char[123]. The problem is that valgrind detects a mismatch between the usage of new and delete variants. While i use new[](unsigned) to allocate memory, the shared_ptr destructor uses delete(void*) to deallocate it, and valgrind warns whenever you are using the "incorrect" deallocator for an allocation.

In more practical terms, i wrote this test case to show what i mean:

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

The valgrind report says

==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)

I want to avoid valgrind filters if possible.

What is the correct way to allocate an arbitrary amount of data and return as a std::shared_ptr<const void>?


回答1:


If you give shared_ptr<T> a T pointer, it assumes that you created a single object and implies the deleter delete p;. If your allocation was actually performed with array-new, you need to pass an appropriate deleter that performs delete[] p;. You can reuse std::default_delete if you like:

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

(You don't even need the outer cast, since the conversion is implied.)

In C++17, shared_ptr supports arrays, so you can say

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

there and get the correct deleter (and then convert to void).



来源:https://stackoverflow.com/questions/42663978/correct-way-to-allocate-memory-to-stdshared-ptr

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!