In the following code , I am not able to understand why the destructor of the class Buf
is invoked twice. When debugging I can see that it is being invoked the first time when the running thread is leaving the function Test::produce
. The second time is when leaving the main function which essentially is when destructing the class EventQueue
, something I would expect.
However, I dont understand why when leaving the function Test::produce
the destructor of Buf
is invoked. Specifically, I create the class Buf
as a r-value passing it to the EventQueue
and move to its internal cache. In fact, this has created me the problem that I end up trying ti free the same pointer twice which throws an exception.
template<typename T>
class EventQueue{
public:
void offer(T&& t) {
m_queue.try_emplace(std::this_thread::get_id()).first->second.push(std::move(t));
};
std::unordered_map<std::thread::id, std::queue<T>> m_queue;
};
class Buf{
const uint8_t *m_data;
const size_t m_size;
public:
Buf(const uint8_t *data, size_t size) : m_data(data), m_size(size) { }
size_t size() const { return m_size; }
const uint8_t *data() const { return m_data; }
~Buf()
{
std::cout << "dtor called " << std::endl;
free((void *)m_data);
}
};
class Test{ and was not expecting
public:
Test(shared_ptr<EventQueue<Buf>> buf) : m_buf(buf)
{
std::thread t1 = std::thread([this] { this->produce(10); });
t1.detach();
};
void produce(int msg_size) {
m_buf->offer(Buf(new uint8_t[msg_size], 10));
}
std::shared_ptr<EventQueue<Buf>> m_buf;
};
int main()
{
auto event_queue = std::make_shared<EventQueue<Buf>>();
Test tt(event_queue);
return 0;
}