只是漏水?还是未定义的行为?

Just leaking? Or undefined behavior?

在旧的连接池实现中,我发现了这个美(强烈简化):

#include <memory>
#include <queue>

struct Connection
{
};

auto pool = std::queue<std::shared_ptr<Connection>>{};

auto pushConnection(Connection* connection) -> void
{
  // This uses pushConnection as custom deleter in the shared_ptr
  pool.emplace(connection, pushConnection);
}

int main()
{
  pushConnection(new Connection{});
}

最初的想法是您可以从池中获取连接,完成后,自定义删除器 (pushConnection) 会自动 return 将其添加到池中。

然而,使用相同的自定义删除器将连接存储在池中不仅仅是有点奇怪。

至少存在资源泄漏:当池在程序结束时超出范围时,将调用 queue 的析构函数。这将破坏 shared_ptrs,这将调用他们的自定义删除器,它将连接放回队列中。

我想知道,将 emplace 变成一个当前正在被销毁的 queue 是否也是未定义的行为?

正如我评论的那样,内存泄漏源于 new Connection{}

程序是UB吗?我觉得是这样的。 std::queue 使用 std::deque 作为默认容器。 The documentation of std::deque::emplace 说:"All iterators, including the past-the-end iterator, are invalidated." 由于 std::deque 的析构函数遍历元素,因此结果必须是 UB。