我有以下简单的代码示例:
#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;
}
在 create_resource
中创建的唯一指针 r
在函数结束时超出范围。至少这是我对范围的理解。
那么由唯一指针包裹的实际资源如何仍然可以访问并且确实会产生段错误,因为它拥有的唯一指针应该超出范围并删除它?
编译使用:g++ test.cpp -std=c++14
最佳答案
是,您对函数作用域的理解是正确的。 std::unique_ptr<resource>
将在 create_resource
之后销毁功能范围。
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?
由于上述原因,您在 main
中收到的内容
resource *r = create_resource();
是一个悬挂指针。访问它将导致 undefined bahviour因此任何事情都可能发生。在您的情况下,这是一个段错误。
为了解决这个问题,您可以返回 std::unique_ptr<resource>
本身来自 create_resource
功能
#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;
}
关于C++ 智能指针范围和资源删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63158352/