C++ 智能指针范围和资源删除
C++ Smart Pointers Scope and Resource Deleting
我有以下简单的代码示例:
#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,因此任何事情都可能发生。在你的情况下,这是一个分段错误。
为了解决这个问题,您可以 return 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;
}
The unique pointer r created in create_resource() goes out of scope at
the end of the function. At least this is my understanding of scope.
这是正确的——当 create_resource()
returns 时,std::unique_ptr
的析构函数执行并删除它持有的 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 ?
create_resource()
是 return 悬空指针 -- 也就是说,指向 resource
对象先前所在的内存位置的指针,但是由于 resource
对象被删除,指针不再可用。尝试使用取消引用悬空指针将导致未定义的行为,包括在某些情况下的分段错误。
处理这种情况的正确方法是 create_resource()
return 一个 std::unique_ptr<resource>
而不是 resource *
.
The unique pointer 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
这个假设是错误的。在函数 returns.
之后,它不再 可访问
程序的行为未定义。它通过无效指针调用成员函数。
我有以下简单的代码示例:
#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,因此任何事情都可能发生。在你的情况下,这是一个分段错误。
为了解决这个问题,您可以 return 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;
}
The unique pointer r created in create_resource() goes out of scope at the end of the function. At least this is my understanding of scope.
这是正确的——当 create_resource()
returns 时,std::unique_ptr
的析构函数执行并删除它持有的 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 ?
create_resource()
是 return 悬空指针 -- 也就是说,指向 resource
对象先前所在的内存位置的指针,但是由于 resource
对象被删除,指针不再可用。尝试使用取消引用悬空指针将导致未定义的行为,包括在某些情况下的分段错误。
处理这种情况的正确方法是 create_resource()
return 一个 std::unique_ptr<resource>
而不是 resource *
.
The unique pointer 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
这个假设是错误的。在函数 returns.
之后,它不再 可访问程序的行为未定义。它通过无效指针调用成员函数。