将 unique_ptr 传递给完成处理程序时,Boost ASIO“错误地址”错误

问题描述 投票:0回答:1

我正在尝试使用 ASIO 实现一个简单的 TCP 服务器。这里的主要区别是我使用

std::unique_ptr
来保存缓冲区而不是原始指针,并且我将它们移动到完成处理程序中以延长其生命周期。

这是代码,它工作得很好(我猜)

void do_read() {
    auto data = std::make_unique<uint8_t[]>(1500);
    auto undesired_var = boost::asio::buffer(data.get(), 1500);
    socket_.async_read_some(
           undesired_var,
           [self = shared_from_this(), data = std::move(data)](auto ec, auto len) mutable {
                if (!ec) {
                    std::cout << "Received " << len << " bytes :)" << std::endl;
                } else {
                    std::cout << "Read error: " << ec.message() << std::endl;
                }
           }
    );
}

运行上面的代码,我得到以下输出:

/tcp_echo/cmake-build-debug/bin/tcp_server 6666
Received 9 bytes :)

请注意,我创建了一个名为

undesired_var
的变量来保存
boost::asio::mutable_buffer
数据。 当我尝试通过直接在
socket_.async_read_some
调用中创建这些变量来删除它们时:

void do_read() {
    auto data = std::make_unique<uint8_t[]>(1500);
    socket_.async_read_some(
            boost::asio::buffer(data.get(), 1500),
            [self = shared_from_this(), data = std::move(data)](auto ec, auto len) mutable {
            if (!ec) {
                std::cout << "Received " << len << " bytes :)" << std::endl;
            } else {
                std::cout << "Read error: " << ec.message() << std::endl;
            }
        }
    );
}

我得到以下输出

tcp_echo/cmake-build-debug/bin/tcp_server 6666
Read error: Bad address

似乎在第二种情况下,我的

std::unique_ptr
过早地被破坏了,但我可以找出原因。我错过了什么吗?

c++ boost undefined-behavior unique-ptr asio
1个回答
1
投票

是的,这是参数表达式的求值顺序。

std::move
可能会在您
.get()
之前发生。

另一个错误:

此外,这里似乎有一个很大的问题:

auto data = std::make_unique<uint8_t>(1500);

动态分配一个无符号字符(

uint8_t
),它是从整数值
1500
初始化的。分配的大小为 1(1 字节)。

auto undesired_var = boost::asio::buffer(data.get(), 1500);

您使用它时就好像它是 1500 字节一样。哎呀。您可能的意思是:

auto data = std::make_unique<uint8_t[]>(1500);

data
的类型现在是
std::unique_ptr<uint8_t[], std::default_delete<uint8_t[]>>
,这是完全不同的模板专业化

© www.soinside.com 2019 - 2024. All rights reserved.