使用shared_ptr触发std::bad_weak_ptr异常的问题求解
解决
std::bad_weak_ptr异常问题 这个坑我之前也踩过,根源在于你对std::enable_shared_from_this的使用前提理解错了,跟你的loop指针是否为空完全没关系。
问题原因
std::enable_shared_from_this提供的shared_from_this()成员函数,只有当当前对象已经被至少一个std::shared_ptr实例托管的时候才能安全调用。而你的代码里:
int main() { Request r; // 这里是栈上创建的对象,没有被任何shared_ptr管理 r.add_inself(); // ... }
Request对象是直接在栈上构造的,没有被std::shared_ptr持有,这时候调用shared_from_this()就会触发std::bad_weak_ptr异常——因为enable_shared_from_this内部的weak_ptr还没有被初始化。
你的loop虽然是有效的shared_ptr,但它是Request的一个成员,和Request对象本身是否被shared_ptr托管是完全无关的两个事情。
解决方案
把Request对象改成用std::shared_ptr来创建,让它一开始就被shared_ptr托管:
修改后的完整代码:
#include <iostream> #include <vector> #include <memory> using namespace std; class Request; typedef std::shared_ptr<Request> RequestPtr; class EventLoop { public: EventLoop(); ~EventLoop(); vector<RequestPtr> relist; void add_request(RequestPtr re) { relist.push_back(re); } }; typedef std::shared_ptr<EventLoop> EventLoopPtr; EventLoop::EventLoop() {} EventLoop::~EventLoop() {} class Request: public std::enable_shared_from_this<Request> { public: Request(); ~Request(); EventLoopPtr loop; void add_inself() { loop->add_request(shared_from_this()); cout << "Yes, success adding into it" << endl; } }; Request::Request(): loop(std::make_shared<EventLoop>()) {} Request::~Request() {} int main() { auto r = std::make_shared<Request>(); // 用shared_ptr托管Request对象 r->add_inself(); std::cout << "END" << std::endl; return 0; }
额外提醒
如果你非要在栈上创建Request对象(不推荐,容易出内存管理混乱),可以通过自定义删除器让shared_ptr不释放栈内存,但这种写法违背了shared_ptr的设计初衷,仅作特殊场景参考:
int main() { Request r; shared_ptr<Request> ptr(&r, [](Request*){}); // 空删除器,不释放对象 r.add_inself(); // 现在可以安全调用了 std::cout << "END" << std::endl; return 0; }
内容的提问来源于stack exchange,提问作者夜听风雨声
相关产品推荐
相关产品推荐

