gpt4 book ai didi

c++ - boost::shared_ptr、std::map 和 valgrind - 我有内存泄漏吗?

转载 作者:行者123 更新时间:2023-11-30 02:10:10 29 4
gpt4 key购买 nike

好的。我正在使用 boost::shared_ptr 在 map 中存储几个对象。整数值映射到 shared_ptr 到我正在使用的对象。

void HandlerMsgHandler::addHandler(uint8_t key, boost::shared_ptr<NetworkHandler> handler) 
{
handlers[key] = handler;
}

此代码在 valgrind 中失败,查看下面的错误消息。如果查看方法链的开头,您会发现在 UdpServer 类中,我将来自测试类的 addHandler 请求转发到名为 HandlerMsgHandler 的内部类中。

这个方法是这样的:

void UdpServer::addHandler(uint8_t key, boost::shared_ptr<NetworkHandler> handler)
{
dynamic_cast<HandlerMsgHandler*>(sysMsgHandlers[network::handler])->addHandler(key, handler);
}

和调用点:

server.addHandler(1, boost::shared_ptr<net::NetworkHandler>(new _NetworkHandler(networkHandlerFailed)));
server.addHandler(2, boost::shared_ptr<net::NetworkHandler>(new SimpleIntMessageHandler(simpleIntFailed)));

我需要转换,因为我有客户端消息处理程序,以及处理某些其他情况(例如错误)的网络/系统消息处理程序。当有效消息已发送到客户端 NetworkHandler 时,将调用 HandlerMsgHandler。

我不确定您需要对设计了解多少,也许错误对您来说是显而易见的?

更新:

sysMsgHandlers 声明为 std::map<SysMessage, NetworkHandler*> sysMsgHandlers; ,而 sysMsgHandlers 是在内部启动的:

sysMsgHandlers[handler] = new HandlerMsgHandler();
sysMsgHandlers[error] = new ErrorMsgHandler();

我在这里没有使用任何花哨的指针类型,因为它都是内部的。我遍历 sysMsgHandlers 映射并删除指针(我已验证会发生这种情况)。

更新 2:

更多信息。我正在删除包含 map 的对象。

我的 UdpServer 析构函数中有这段代码:

for(auto iter = sysMsgHandlers.begin(); iter != sysMsgHandlers.end(); iter++)
{
LOG("MsgHandlers deleted");
delete iter->second;
}

这会向 std::cout 提供以下输出:(以及其他一些调试消息)

 : Listening started
: Connecting to socket : 1
: Sending message
: Received in buffer
: Received : 24 bytes.
: Sys msg = 1
: Handling request to: 1
: Stopping manager
: MsgHandlers deleted
: MsgHandlers deleted

这仍然是 valgrind 的输出:

==26633== 192 (56 direct, 136 indirect) bytes in 1 blocks are definitely lost in loss record 21 of 35
==26633== at 0x4C28973: operator new(unsigned long) (vg_replace_malloc.c:261)
==26633== by 0x4258AF: __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > > >::allocate(unsigned long, void const*) (new_allocator.h:89)
==26633== by 0x4257A7: std::_Rb_tree<unsigned char, std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> >, std::_Select1st<std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > >, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > > >::_M_get_node() (stl_tree.h:359)
==26633== by 0x425622: std::_Rb_tree_node<std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > >* std::_Rb_tree<unsigned char, std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> >, std::_Select1st<std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > >, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > > >::_M_create_node<std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > const&>(std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > const&&&) (stl_tree.h:391)
==26633== by 0x42526E: std::_Rb_tree<unsigned char, std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> >, std::_Select1st<std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > >, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > > >::_M_insert_(std::_Rb_tree_node_base const*, std::_Rb_tree_node_base const*, std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > const&) (stl_tree.h:881)
==26633== by 0x4253ED: std::_Rb_tree<unsigned char, std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> >, std::_Select1st<std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > >, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > > >::_M_insert_unique(std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > const&) (stl_tree.h:1177)
==26633== by 0x424CA9: std::_Rb_tree<unsigned char, std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> >, std::_Select1st<std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > >, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > > >::_M_insert_unique_(std::_Rb_tree_const_iterator<std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > >, std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > const&) (stl_tree.h:1217)
==26633== by 0x424931: std::map<unsigned char, boost::shared_ptr<chat::server::network::NetworkHandler>, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > > >::insert(std::_Rb_tree_iterator<std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > >, std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > const&) (stl_map.h:540)
==26633== by 0x42463E: std::map<unsigned char, boost::shared_ptr<chat::server::network::NetworkHandler>, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, boost::shared_ptr<chat::server::network::NetworkHandler> > > >::operator[](unsigned char const&) (stl_map.h:450)
==26633== by 0x424163: chat::server::network::HandlerMsgHandler::addHandler(unsigned char, boost::shared_ptr<chat::server::network::NetworkHandler>) (sysnetworkhandler.cpp:19)
==26633== by 0x4120F1: chat::server::network::UdpServer::addHandler(unsigned char, boost::shared_ptr<chat::server::network::NetworkHandler>) (udpserver.cpp:38)
==26633== by 0x404938: chat::test::server::testCanSendToSelf(bool&) (main.cpp:95)

最佳答案

std::map是红黑树,valgrind 提示 std::_Rb_tree_node<std::pair<..., ...> > 的分配. map 的节点的树是泄漏的节点。

我猜这个 Actor 一定与泄密有关:

dynamic_cast<HandlerMsgHandler*>(sysMsgHandlers[network::handler])->addHandler(key, handler);

你确定表达式 sysMsgHandlers[network::handler]返回指向 boost::shared_ptr指针(而不是 HandlerMsgHandler) ?

编辑: 下一个最可能的原因是 sysMsgHandlers[handler]返回 ErrorMsgHandler实例。

编辑,2 月 2 日: 是您的 NetworkHandler析构函数虚拟?如果不是,则 map<uint8_t boost::shared_ptr<NetworkHandler> > handlers 的析构函数不会被调用,你会在那里泄漏 map 的节点。

查看 C++ FAQ .

Q: When should my destructor be virtual?

A: When someone will delete a derived-class object via a base-class pointer. When you say delete p, and the class of p has a virtual destructor, the destructor that gets invoked is the one associated with the type of the object *p, not necessarily the one associated with the type of the pointer. This is A Good Thing.

关于c++ - boost::shared_ptr、std::map 和 valgrind - 我有内存泄漏吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4868417/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com