I have the following simple code example:
#include <iostream>
#include <utility>
#include <memory>
using namespace std;
class resource
{
public:
void print() { cout << "Class Still Alive" << endl; };
};
resource* create_resource()
{
std::unique_ptr<resource> r = std::make_unique<resource>();
return r.get();
}
void execute_resource(resource* r)
{
r->print();
}
int main()
{
resource* r = create_resource();
execute_resource(r);
return 0;
}
The unique ptr r
created in create_resource
goes out of scope at the end of the function. At least this is my understanding of scope.
So how is the actual resource wrapped by the unique pointer still reachable and does create a segmentation fault since its owning unique pointer should have gone out of scope and deleted this?
Compiling using: g++ test.cpp -std=c++14
Yes, your understanding is correct about the function scope. The std::unique_ptr<resource>
will be destroyed after the create_resource
function scope.
So how is the actual resource wrapped by the unique pointer still reachable and does create a segmentation fault since its owning unique pointer should have gone out of scope and deleted this?
Because of the reason mentioned above, what you receiving here in the main
resource *r = create_resource();
is a dangling pointer. Accessing it will cause the undefined bahviour and hence anything can happen. In your case, it is a segmentation fault.
In order to fix the issue, you can return the std::unique_ptr<resource>
itself from the create_resource
function
#include <iostream>
#include <utility>
#include <memory>
class resource
{
public:
void print() const // can be const
{
std::cout << "Class Still Alive\n";
};
};
std::unique_ptr<resource> create_resource()
{
return std::make_unique<resource>(); // return the std::unique_ptr<resource>
}
void execute_resource(resource* r)
{
r->print();
}
int main()
{
auto r = create_resource();
execute_resource(r.get()); // pass the pointer to execute!
return 0;
}