为什么下面的代码不起作用?
class A {};
void f(A* a) {
shared_ptr<A> c(a);
}
int main() {
auto a = make_shared<A>();
auto b = a.get();
f(b);
return 0;
}
在f
范围的最后,我的程序崩溃了。可能是什么导致了这个?是否有某些东西试图被删除而且不存在?
答案 0 :(得分:5)
您有两个不相关的共享指针,它们都在尝试管理同一个资源。这导致了不确定的行为。特别是,当他们超出范围时,他们都会尝试删除资源。
一般情况下,不要这样做:)
答案 1 :(得分:2)
class A {};
void f(A* a) {
shared_ptr<A> c(a);
}
int main() {
auto a = make_shared<A>();
auto b = a.get();
f(b);
return 0;
}
这里发生的事情是,您的初始make_shared()
正在创建拥有shared_ptr
的{{1}}。当您调用A
时,您正在创建第二个不相关的共享指针,也认为它拥有相同的数据。当函数调用f(b)
结束时,本地共享ptr变量被销毁;这将检查引用计数是否为零(它将是),因此删除该对象。然后,当main函数结束时,局部变量f()
的析构函数运行,检查引用计数是否为零(同样,它将是),因此尝试再次删除相同的数据。这种双重删除是造成崩溃的原因。
有两种解决方案:最简单的方法是不处理原始指针,并将a
直接传递给shared_ptr
。然后引用计数将正常工作,数据只会被销毁一次。
另一种方法是让您的班级f()
公开继承自A
。然后,您可以使用std::enable_shared_from_this
方法从原始指针“恢复”共享指针(具有正确的引用计数),即
shared_from_this()
您可以阅读class A : public std::enable_shared_from_this<A> {};
void f(A* a) {
shared_ptr<A> c = a->shared_from_this();
}
here。