shared_ptr语言 - 为什么它会破裂
shared_ptr - why does it break?
在开发树状数据结构时,我写了这样的东西:
#include <memory>
class Node: public std::enable_shared_from_this<Node> {
public:
void set_root(Node & n);
private:
std::shared_ptr<Node> root;
std::shared_ptr<Node> leaf;
};
void Node::set_root(Node & n) {
root = n.shared_from_this();
n.leaf = shared_from_this();
}
int main() {
Node n1, n2;
n1.set_root(n2);
}
代码使用 clang 编译,但中断运行时("libc++abi.dylib:终止,未捕获类型为 std::__1::bad_weak_ptr:bad_weak_ptr") 为什么?
编辑因此,根据答案,我想出了似乎有效的版本:
#include <memory>
class Node;
typedef std::shared_ptr<Node> Node_SP;
class Node: public std::enable_shared_from_this<Node> {
public:
void set_root(Node & n);
private:
std::shared_ptr<Node> root;
std::shared_ptr<Node> leaf;
};
void Node::set_root(Node & n) {
root = n.shared_from_this();
n.leaf = shared_from_this();
}
int main() {
Node_SP n1 = std::shared_ptr<Node>(new Node);
Node_SP n2 = std::shared_ptr<Node>(new Node);
n1->set_root(*n2);
}
为了完成它的工作,enable_shared_from_this<Node>
必须为自己存储一个weak_ptr<Node>
。此weak_ptr
默认构造为 null。当构造shared_ptr
以接管对象的所有权时,无论是 vía make_shared
还是通过传递原始指针,它将所述weak_ptr
设置为引用该新shared_ptr
。如果随后对对象调用shared_from_this()
,则weak_ptr
将lock
ed,并且可以返回另一个shared_ptr
。
但是,在您的情况下,没有shared_ptr
持有n1
和n2
,因此当调用shared_from_this()
时,lock
在空weak_ptr
上执行,导致所述异常。
长话短说:不要对不属于shared_ptr
的对象调用shared_from_this()
- 尤其是不要像示例中那样在基于堆栈的对象上调用。
shared_ptr
假定对象是在堆上分配的,但您已在堆栈上分配了它。
请改用new
,让shared_ptr
为您呼叫delete
。
在对对象 t 调用 shared_from_this 之前,必须有一个拥有 t 的 std::shared_ptr。
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 为什么在全局范围内使用"extern int a"似乎不行?
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
- 为什么 ( ( cout << ptr; cout << "n" << ++ptr; )) 和 ( ( cout << ptr << "
- 为什么在将常量 ptr 分配给常量引用时没有收到编译错误?
- 为什么(常量字符*)ptr 不被视为左值
- 由于 RPTR->num=30 与 (*rptr).num=30 相同,但是*((*rptr).ptr).name 不起作用为什么?
- 带智能ptr的Pimpl-为什么需要构造函数/析构函数
- 为什么Mozilla开发者指南更喜欢if(ptr)而不是if(ptr!=nsnull)
- 为什么asm中的这种差异对性能很重要(在未优化的ptr++与++ptr循环中)
- 为什么非常量ptr不能隐式地将ptr转换为常量作为模板中的参数
- 为什么我会在不存储 ptr 的情况下调用新
- 为什么 std::string{ "const char ptr" } 有效?
- 为什么这个显式析构函数会导致共享ptr中的内存损坏
- 为什么 gcc 4.9.0 中没有定义"void operator delete(void* ptr, std::size_t size) noexcept;"?
- 为什么int** ptr在访问ptr[i][j]时不指向与int arr[3][3]相同的地址?
- 为什么不使用空自动PTR不会终止程序?
- 为什么 *ptr++ 不更改 pointee 的值,但 (*ptr)++ 会更改?