Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

change pointer in std::unique_ptr without destroy it

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;
   }
};
like image 394
Nick Avatar asked Sep 10 '16 17:09

Nick


People also ask

Can unique_ptr be moved?

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.

Does unique_ptr call Delete?

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.

Is unique_ptr a pointer?

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.

Should I use unique_ptr or shared_ptr?

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.


1 Answers

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;
}
like image 194
Barry Avatar answered Sep 30 '22 06:09

Barry