Home > Net >  Pass reference to function that takes `std::unique_ptr`
Pass reference to function that takes `std::unique_ptr`

Time:05-06

I have a reference to my object of type MyType, but I need to call a function, say myFunction that takes a std::unique_ptr<MyType>. What is the correct way to call myFunction? My attempt below seems to cause an "invalid pointer" error:

#include <memory>

class MyType {};
MyType myGlobalObj;

MyType& myGetter () {
    return myGlobalObj;
}

void myFunction (std::unique_ptr<MyType> ptr) {
    // Do important stuff
}

int main () {
    MyType& myObj = myGetter();
    std::unique_ptr<MyType> myPtr;
    myPtr.reset(&myObj);
    myFunction(std::move(myPtr)); // This causes "invalid pointer" at run time.
    myPtr.release();
    return 0;
}

CodePudding user response:

What you are trying to do is not possible without either doing a (deep-)copy of myGlobalObj or modifying myFunction.

A std::unique_ptr takes ownership of the memory that is used to store the contained object. That means that the std::unique_ptr may free (or reallocate, or whatever) the memory that it 'owns'. What it would do in your case: As soon as the ptr variable goes out of scope at the end of myFunction, it will attempt to free the memory that it points to. Since myGlobalObj is a global variable, its memory may never be freed (before a controlled shutdown of your program…)

Thus, you should not ever wrestle a global object into a std::unique_ptr (or a std::shared_ptr, for that matter). If there is really no way of refactoring that method to take anything else than a std::unique_ptr, you must make a copy (on the heap!) of myGlobalObj, wrap that into a std::unique_ptr, and pass it to myFunction. Keep in mind that this way, myFunction loses the ability to modify myGlobalObj.

  • Related