通过引用lambda传递weak_ptr

Passing weak_ptr by reference to lambda

本文关键字:weak ptr 传递 lambda 引用      更新时间:2024-09-29

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

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

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

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

// 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();
}

如评论中所述

std::weak_ptr<s::Channel>套接字是一个局部变量,它在函数返回后被销毁。稍后调用回调时,它引用的是一个不存在的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);
}
})
}