Is it possible to use a C++ smart pointers together with C's malloc?
If you are using shared_ptr
or unique_ptr
, you can specify a custom deleter. For example,
struct free_delete
{
void operator()(void* x) { free(x); }
};
This can be used with shared_ptr
like so:
std::shared_ptr<int> sp((int*)malloc(sizeof(int)), free_delete());
If you are using unique_ptr
, the deleter is a part of the unique_ptr
's type, so the deleter needs to be specified as a template argument:
std::unique_ptr<int, free_delete> up((int*)malloc(sizeof(int)));
However, it is better to use exceptions correctly, rather than avoiding them, when writing C++, especially with respect to allocation failures. In most cases, you cannot successfully recover from an allocation failure in the function trying to do the allocation, so exceptions can help you to handle the error where you are actually capable of handling it.
You can use nothrow keyword with the new operator, which will return NULL rather that throw an exception. For details see link below: http://www.cplusplus.com/reference/std/new/nothrow/
The best solution is to use new (std::nothrow) Type
. This will act just like new Type
, but will give null rather than throwing if it fails. This will be much easier than trying to make malloc
behave like new
.
If you really must use malloc
, then remember to construct and destruct the object correctly:
void* memory = malloc(sizeof(Type));
Type* object = new (memory) Type;
object->~Type();
free(object); // or free(memory)
You can use this with a some smart pointers by giving it a custom deleter:
void malloc_deleter(Type* object)
{
object->~Type();
free(object);
}
if (void* memory = malloc(sizeof(Type)))
{
Type* object = new (memory) Type;
std::shared_ptr<Type> ptr(object, malloc_deleter);
DoStuff(ptr);
}
But this would be much simpler using non-throwing new:
if (Type* object = new (std::nothrow) Type)
{
std::shared_ptr<Type> ptr(object);
DoStuff(ptr);
}