【发布时间】:2021-09-04 14:48:21
【问题描述】:
据我所知,下面的代码是正确的:
#include <iostream>
#include <functional>
struct A
{
std::function<void ()> func;
int value = 5;
~A() { func(); }
};
int main()
{
A* p_a = new A();
p_a->func = [&p_a]() { std::cout << p_a->value; };
delete p_a;
return 0;
}
但下面的代码不是,会导致分段错误:
#include <memory>
int main()
{
std::unique_ptr<A> p_a = std::make_unique<A>();
p_a->func = [&p_a]() { std::cout << p_a->value; };
p_a = {};
return 0;
}
std::unique_ptr 首先清除其内部指针,然后删除对象,从而防止访问被销毁的对象。
它是干什么用的?这背后的逻辑是什么?
EDIT1:
标记的问题是重复的。如果删除器抛出异常(如果我没有误解的话),我更喜欢 std::uniqu_ptr 保留旧对象。
【问题讨论】:
-
This 似乎有些相关。
-
另一方面,第一个示例没有产生分段错误并不意味着它是有效的。
-
第二个例子是调用带有智能指针引用的函数。在调用析构函数时,智能指针已被重置为 nullptr。取消引用 nullptr 是未定义的行为。一种解决方法是
p_a->func = [&p_a]() { if (p_a) std::cout << p_a->value << "\n"; }; -
@super
A::func在析构函数开始执行时仍然存在。 -
@Eljay 这就是 OP 所说的。我想问题是 - 至少我是怎么理解的 - 为什么顺序不是:首先删除当前管理的对象,然后用
nullptr替换它。
标签: c++