I have a boost::asio::io_context
that I want to move around. Since I cannot move it without a pointer, I use an std::unique_ptr
. However, I noticed that when running with -fsanitize=address
heap-use-after-free.
I checked the pointed to address before and after the move and it is exactly the same. Have I made an error or is the sanitizer just overreacting here?
#include <boost/asio.hpp>
#include <memory>
#include <iostream>
int main()
{
std::unique_ptr<boost::asio::io_context> io_ptr{
std::make_unique<boost::asio::io_context>()
};
boost::asio::steady_timer timer{*io_ptr, std::chrono::seconds{1}};
std::cout << "io_ptr address: " << io_ptr.get() << std::endl;
// on my machine: io_ptr address: 0x602000000010
timer.async_wait([](const boost::system::error_code&) {
std::cout << "Timer called\n"; // gets called
});
std::unique_ptr<boost::asio::io_context> io_ptr2{std::move(io_ptr)};
std::cout << "io_ptr address: " << io_ptr2.get() << std::endl;
// same: io_ptr address: 0x602000000010
io_ptr2->run_one();
std::cout << "Done\n"; // gets printed
return 0;
}
I tried printing something inside the async_wait
call and that gets printed, so the sanitizer happens react to the destruction of the timer it seems.
Compiler: GCC 11.4.0
Keep in mind that destructs happen in reverse order -- which means your second std::unique_ptr
, which owns the io_context
, is destroyed BEFORE your timer object....