I have C++ code that uses raw pointer with C functions malloc
, free
and realloc
.
I am thinking to change it to smart pointer, but I really want to keep the realloc
functionality, because I believe it is much better than new
, since it does not need to "move" the contents every time.
How I can refactor this with std::unique_ptr
?
Here is some pseudo code (I realize this code is not 100% safe. In fact I never tried to compile it)
class Demo{
char *ptr;
Demo(size_t size) : ptr( malloc(size) ){}
bool resize(size_t size){
char *ptr_new = realloc(ptr, size);
if (ptr_new == nullptr){
return false; // fail
}
// here is tricky part with std::unique_ptr,
// ptr is already deleted...
ptr = ptr_new;
return true;
}
};
A unique_ptr can only be moved. This means that the ownership of the memory resource is transferred to another unique_ptr and the original unique_ptr no longer owns it. We recommend that you restrict an object to one owner, because multiple ownership adds complexity to the program logic.
An explicit delete for a unique_ptr would be reset() . But do remember that unique_ptr are there so that you don't have to manage directly the memory they hold. That is, you should know that a unique_ptr will safely delete its underlying raw pointer once it goes out of scope.
std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope.
Use unique_ptr when you want to have single ownership(Exclusive) of the resource. Only one unique_ptr can point to one resource. Since there can be one unique_ptr for single resource its not possible to copy one unique_ptr to another. A shared_ptr is a container for raw pointers.
The way to reassign a pointer without deleting it is to use release()
:
auto old_ptr = unique.release();
unique.reset(new_ptr);
So in your code that would be something like:
struct free_deleter {
void operator(void* p) const { free(p); }
};
std::unique_ptr<char, free_deleter> ptr; // NB: malloc must be paired with free, not delete
bool resize(size_t size) {
char* ptr_new = realloc(ptr.get(), size);
if (!ptr_new) {
return false;
}
ptr.release();
ptr.reset(ptr_new);
return true;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With