You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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,提问作者夜听风雨声

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:50:15