首页 > 解决方案 > 通过引用 lambda 传递weak_ptr

问题描述

我在程序运行时观察到未定义的行为,我怀疑它可能是由weak_ptr 引起的。

调用了套接字的发送函数,但它无法映射套接字,但是如果我删除 Lambdas,它可以映射套接字。

工作函数之前是同步的,没有任何问题,但现在在将 Lambda 添加到工作函数后会导致未定义的行为。

这真的不安全吗?如果是这样,我应该改用什么?

// Global Socket
std::shared_ptr<s::Channel> gSocket;

void worker(std::weak_ptr<s::Channel> socket)
{
    auto &request = requests.emplace_back();

    request.onMessage([&](std::string data) {
        if (auto channel = socket.lock())
        {
            channel->send(data);
        }
    })

    request.onError([&](std::string data) {
        if (auto channel = socket.lock())
        {
            channel->send(data);
        }
    })
}

int main() {
    broker->onInit([&]() {
        // Shared PTR
        gSocket = createConnection();

        gSocket->onOpen([&, wS = make_weak_ptr(gSocket)]() {
            if (auto c = wS.lock())
            {
                worker(c);
            }
        });
    })

    broker.init();
}

标签: c++

解决方案


如评论中所述

std::weak_ptr<s::Channel>socket是一个局部变量,函数返回后销毁。稍后调用回调时,它指的是一个不存在的weak_ptr 实例。

您可以通过按值捕获来修复它socket

void worker(std::weak_ptr<s::Channel> socket)
{
    auto &request = requests.emplace_back();

    request.onMessage([socket, &request](std::string data) {
        if (auto channel = socket.lock())
        {
            channel->send(data);
        }
    })

    request.onError([socket, &request](std::string data) {
        if (auto channel = socket.lock())
        {
            channel->send(data);
        }
    })
}

推荐阅读