我正在使用c ++中的TCP套接字制作网络 当我试图将数据包处理程序保存在地图中时,我遇到了问题 这是我的实施:
using handler_t = std::function<void (NetworkClient *, NetworkMessage *)>;
using handlers_t = std::unordered_map<int32_t, handler_t>;
template <typename T, typename V>
using typed_handler_t = void (T::*)(NetworkClient *, V *);
class AbstractPacketHandler {
public:
void init() {
define_handlers(_handlers);
}
void parse_packet(NetworkClient *client, NetworkMessage *msg) {
lock_t lock(_locker);
try {
_handlers.at(msg->getProtocolId())(client, msg);
} catch (std::exception &e) {
throw std::runtime_error("no handler found for protocol id " + msg->getProtocolId());
}
}
virtual void define_handlers(handlers_t &handlers) = 0;
protected:
template <typename T, typename V>
handler_t handler(T &holder, typed_handler_t<T, V> addr) {
return [&holder, &addr](NetworkClient *client, NetworkMessage *msg) mutable {
(holder.*addr)(client, dynamic_cast<V *>(msg));
};
}
private:
handlers_t _handlers;
std::mutex _locker;
};
数据包处理程序实现
using Self = MasterPacketHandler;
void Self::define_handlers(handlers_t &handlers) {
handlers[HelloConnectMessage::PROTOCOL_ID] = handler<Self, HelloConnectMessage>(*this, &Self::onHello);
handlers[AwesomeMessage::PROTOCOL_ID] = handler<Self, AwesomeMessage>(*this, &Self::onAwesomeMsg);
}
void Self::onHello(NetworkClient *client, HelloConnectMessage *msg) {
printf("deserialized hellomsg: %d\n", msg->getHelloVar());
}
void Self::onAwesomeMsg(NetworkClient *client, AwesomeMessage *msg) {
printf("deserialized awesome: %s %d\n", msg->getAwesome(), msg->getSomeNumber());
}
此代码编译没有警告或错误。但是在收到消息的运行时,我得到segmentation fault
在多次尝试修复后,我尝试使用valgrind
进行调试
返回错误下方:
==14561== Conditional jump or move depends on uninitialised value(s)
==14561== at 0x117CDD: std::function<void (NetworkClient*, NetworkMessage*)> AbstractPacketHandler::handler<SlavePacketHandler, AwesomeMessage>(SlavePacketHandler&, void (SlavePacketHandler::*)(NetworkClient*, AwesomeMessage*))::{lambda(NetworkClient*, NetworkMessage*)#1}::operator()(NetworkClient*, NetworkMessage*) (AbstractPacketHandler.h:40)
==14561== Use of uninitialised value of size 8
==14561== at 0x117D3C: std::function<void (NetworkClient*, NetworkMessage*)> AbstractPacketHandler::handler<SlavePacketHandler, AwesomeMessage>(SlavePacketHandler&, void (SlavePacketHandler::*)(NetworkClient*, AwesomeMessage*))::{lambda(NetworkClient*, NetworkMessage*)#1}::operator()(NetworkClient*, NetworkMessage*) (AbstractPacketHandler.h:40)
==14561== Jump to the invalid address stated on the next line
==14561== at 0x0: ???
==14561== by 0x117EEA: std::_Function_handler<void (NetworkClient*, NetworkMessage*), std::function<void (NetworkClient*, NetworkMessage*)> AbstractPacketHandler::handler<SlavePacketHandler, AwesomeMessage>(SlavePacketHandler&, void (SlavePacketHandler::*)(NetworkClient*, AwesomeMessage*))::{lambda(NetworkClient*, NetworkMessage*)#1}>::_M_invoke(std::_Any_data const&, NetworkClient*&&, NetworkMessage*&&) (functional:1731)
==14561== Process terminating with default action of signal 11 (SIGSEGV)
==14561== Bad permissions for mapped region at address 0x0
==14561== at 0x0: ???
==14561== by 0x117EEA: std::_Function_handler<void (NetworkClient*, NetworkMessage*), std::function<void (NetworkClient*, NetworkMessage*)> AbstractPacketHandler::handler<SlavePacketHandler, AwesomeMessage>(SlavePacketHandler&, void (SlavePacketHandler::*)(NetworkClient*, AwesomeMessage*))::{lambda(NetworkClient*, NetworkMessage*)#1}>::_M_invoke(std::_Any_data const&, NetworkClient*&&, NetworkMessage*&&) (functional:1731)
在所有这些错误中,我们都可以看到AbstractPacketHandler:40
,这是我handler
方法的以下代码行。
(holder.*addr)(client, dynamic_cast<V *>(msg));
我不明白错误,所有变量都被初始化,因为它们是函数的参数..我的处理程序方法是否写得正确?