来自导致段错误的函数的 C++ 错误
C++ Error from a function causing seg fault
你好,我有这个函数,我正在尝试从中获取值
struct PlayerMoving
{
int packetType;
int netID;
float x;
float y;
int characterState;
int plantingTree;
float XSpeed;
float YSpeed;
int punchX;
int punchY;
int secondnetID;
};
PlayerMoving *unpackPlayerMoving(BYTE *data)
{
PlayerMoving *dataStruct = new PlayerMoving;
dataStruct->packetType = *(int *)(data);
dataStruct->netID = *(int *)(data + 4);
dataStruct->characterState = *(int *)(data + 12);
dataStruct->plantingTree = *(int *)(data + 20);
dataStruct->x = *(float *)(data + 24);
dataStruct->y = *(float *)(data + 28);
dataStruct->XSpeed = *(float *)(data + 32);
dataStruct->YSpeed = *(float *)(data + 36);
dataStruct->punchX = *(int *)(data + 44);
dataStruct->punchY = *(int *)(data + 48);
return dataStruct;
}
void SendPacketRaw(int a1, std::vector<BYTE> packetData, size_t packetDataSize, void *a4, ENetPeer *peer, int packetFlag)
{
ENetPacket *p;
if (peer) // check if we have it setup
{
if (a1 == 4 && *((BYTE *)&packetData[12]) & 8)
{
p = enet_packet_create(0, packetDataSize + *((DWORD *)&packetData[13]) + 5, packetFlag);
int four = 4;
memcpy(p->data, &four, 4);
memcpy((char *)p->data + 4, &packetData[0], packetDataSize);
memcpy((char *)p->data + packetDataSize + 4, a4, *((DWORD *)&packetData[13]));
enet_peer_send(peer, 0, p);
}
else
{
p = enet_packet_create(0, packetDataSize + 5, packetFlag);
memcpy(p->data, &a1, 4);
memcpy((char *)p->data + 4, &packetData[0], packetDataSize);
enet_peer_send(peer, 0, p);
}
}
}
调用此函数后
void Nothing(ENetPeer *peer, int x, int y)
{
PlayerMoving data;
data.netID = pinfo(peer)->netID;
data.packetType = 0x8;
data.plantingTree = 0;
data.netID = -1;
data.x = x;
data.y = y;
data.punchX = x;
data.punchY = y;
SendPacketRaw(4, packPlayerMoving(&data), 56, 0, peer, ENET_PACKET_FLAG_RELIABLE);
}
导致分段错误
PlayerMoving *pMov = unpackPlayerMoving(tankUpdatePacket);
if (pMov->plantingTree == 18) {
OnPunch(pMov->punchX, pMov->punchY, world, peer, server);
}
else if (pMov->plantingTree == 32) {
onWrench(world, pMov->punchX, pMov->punchY, peer);
}
else
{
OnPlace(pMov->punchX, pMov->punchY, pMov->plantingTree, world, peer, server); //here it show segmentation fault
}
delete pMov;
我遇到了分段错误,所以我决定使用 valgrind 来查看发生了什么
然后我在 SendPacketRaw 中看到了分段错误,但我真的不知道为什么会发生关于如何解决此问题的任何想法?
这就是 valgrind 给我的东西
==38843== Conditional jump or move depends on uninitialised value(s)
==38843== at 0x1189CF: SendPacketRaw(int, std::vector<unsigned char, std::allocator<unsigned char> >, unsigned long, void*, _ENetPeer*, int) (utils.cpp:152)
==38843== by 0x11E327: Nothing(_ENetPeer*, int, int) (worlds.cpp:405)
==38843== by 0x120B6A: Events::Recieve(_ENetHost*, _ENetPacket*, _ENetPeer*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (events.cpp:342)
==38843== by 0x123D7A: Run() (main.cpp:62)
==38843== by 0x123E24: main (main.cpp:87)
==38843==
==38843== Conditional jump or move depends on uninitialised value(s)
==38843== at 0x145119: enet_packet_create (in /home/cmd/Desktop/PRC++/server)
==38843== by 0x118A16: SendPacketRaw(int, std::vector<unsigned char, std::allocator<unsigned char> >, unsigned long, void*, _ENetPeer*, int) (utils.cpp:154)
==38843== by 0x11E327: Nothing(_ENetPeer*, int, int) (worlds.cpp:405)
==38843== by 0x120B6A: Events::Recieve(_ENetHost*, _ENetPacket*, _ENetPeer*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (events.cpp:342)
==38843== by 0x123D7A: Run() (main.cpp:62)
==38843== by 0x123E24: main (main.cpp:87)
==38843==
==38843== Conditional jump or move depends on uninitialised value(s)
==38843== at 0x483B7A0: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==38843== by 0x14C8D8: enet_malloc (in /home/cmd/Desktop/PRC++/server)
==38843== by 0x145134: enet_packet_create (in /home/cmd/Desktop/PRC++/server)
==38843== by 0x118A16: SendPacketRaw(int, std::vector<unsigned char, std::allocator<unsigned char> >, unsigned long, void*, _ENetPeer*, int) (utils.cpp:154)
==38843== by 0x11E327: Nothing(_ENetPeer*, int, int) (worlds.cpp:405)
==38843== by 0x120B6A: Events::Recieve(_ENetHost*, _ENetPacket*, _ENetPeer*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (events.cpp:342)
==38843== by 0x123D7A: Run() (main.cpp:62)
==38843== by 0x123E24: main (main.cpp:87)
==38843==
==38843== Conditional jump or move depends on uninitialised value(s)
==38843== at 0x48429FA: memmove (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==38843== by 0x118A98: SendPacketRaw(int, std::vector<unsigned char, std::allocator<unsigned char> >, unsigned long, void*, _ENetPeer*, int) (utils.cpp:158)
==38843== by 0x11E327: Nothing(_ENetPeer*, int, int) (worlds.cpp:405)
==38843== by 0x120B6A: Events::Recieve(_ENetHost*, _ENetPacket*, _ENetPeer*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (events.cpp:342)
==38843== by 0x123D7A: Run() (main.cpp:62)
==38843== by 0x123E24: main (main.cpp:87)
==38843==
==38843== Conditional jump or move depends on uninitialised value(s)
==38843== at 0x4842BA1: memmove (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==38843== by 0x118A98: SendPacketRaw(int, std::vector<unsigned char, std::allocator<unsigned char> >, unsigned long, void*, _ENetPeer*, int) (utils.cpp:158)
==38843== by 0x11E327: Nothing(_ENetPeer*, int, int) (worlds.cpp:405)
==38843== by 0x120B6A: Events::Recieve(_ENetHost*, _ENetPacket*, _ENetPeer*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (events.cpp:342)
==38843== by 0x123D7A: Run() (main.cpp:62)
==38843== by 0x123E24: main (main.cpp:87)
==38843==
==38843== Conditional jump or move depends on uninitialised value(s)
==38843== at 0x4842B0E: memmove (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==38843== by 0x118A98: SendPacketRaw(int, std::vector<unsigned char, std::allocator<unsigned char> >, unsigned long, void*, _ENetPeer*, int) (utils.cpp:158)
==38843== by 0x11E327: Nothing(_ENetPeer*, int, int) (worlds.cpp:405)
==38843== by 0x120B6A: Events::Recieve(_ENetHost*, _ENetPacket*, _ENetPeer*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (events.cpp:342)
==38843== by 0x123D7A: Run() (main.cpp:62)
==38843== by 0x123E24: main (main.cpp:87)
==38843==
==38843== Invalid read of size 2
==38843== at 0x4842B30: memmove (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==38843== by 0x118A98: SendPacketRaw(int, std::vector<unsigned char, std::allocator<unsigned char> >, unsigned long, void*, _ENetPeer*, int) (utils.cpp:158)
==38843== by 0x11E327: Nothing(_ENetPeer*, int, int) (worlds.cpp:405)
==38843== by 0x120B6A: Events::Recieve(_ENetHost*, _ENetPacket*, _ENetPeer*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (events.cpp:342)
==38843== by 0x123D7A: Run() (main.cpp:62)
==38843== by 0x123E24: main (main.cpp:87)
==38843== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==38843==
==38843==
==38843== Process terminating with default action of signal 11 (SIGSEGV)
==38843== Access not within mapped region at address 0x0
==38843== at 0x4842B30: memmove (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==38843== by 0x118A98: SendPacketRaw(int, std::vector<unsigned char, std::allocator<unsigned char> >, unsigned long, void*, _ENetPeer*, int) (utils.cpp:158)
==38843== by 0x11E327: Nothing(_ENetPeer*, int, int) (worlds.cpp:405)
==38843== by 0x120B6A: Events::Recieve(_ENetHost*, _ENetPacket*, _ENetPeer*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (events.cpp:342)
==38843== by 0x123D7A: Run() (main.cpp:62)
==38843== by 0x123E24: main (main.cpp:87)
==38843== If you believe this happened as a result of a stack
==38843== overflow in your program's main thread (unlikely but
==38843== possible), you can try to increase the size of the
==38843== main thread stack using the --main-stacksize= flag.
==38843== The main thread stack size used in this run was 8388608.
==38843==
==38843== HEAP SUMMARY:
==38843== in use at exit: 11,984,361 bytes in 22,878 blocks
==38843== total heap usage: 93,823 allocs, 70,945 frees, 29,828,594 bytes allocated
==38843==
==38843== LEAK SUMMARY:
==38843== definitely lost: 928 bytes in 3 blocks
==38843== indirectly lost: 4,940 bytes in 16 blocks
==38843== possibly lost: 224 bytes in 2 blocks
==38843== still reachable: 11,978,269 bytes in 22,857 blocks
==38843== suppressed: 0 bytes in 0 blocks
==38843== Rerun with --leak-check=full to see details of leaked memory
==38843==
==38843== Use --track-origins=yes to see where uninitialised values come from
==38843== For lists of detected and suppressed errors, rerun with: -s
==38843== ERROR SUMMARY: 36605 errors from 14 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
您致电:
SendPacketRaw(4, packPlayerMoving(&data), 56, 0, peer, ENET_PACKET_FLAG_RELIABLE);
//^^
所以第四个参数void *a4
就是0
.
因此这一行从 NULL
指针读取:
memcpy((char *)p->data + packetDataSize + 4, a4, *((DWORD *)&packetData[13]));
你好,我有这个函数,我正在尝试从中获取值
struct PlayerMoving
{
int packetType;
int netID;
float x;
float y;
int characterState;
int plantingTree;
float XSpeed;
float YSpeed;
int punchX;
int punchY;
int secondnetID;
};
PlayerMoving *unpackPlayerMoving(BYTE *data)
{
PlayerMoving *dataStruct = new PlayerMoving;
dataStruct->packetType = *(int *)(data);
dataStruct->netID = *(int *)(data + 4);
dataStruct->characterState = *(int *)(data + 12);
dataStruct->plantingTree = *(int *)(data + 20);
dataStruct->x = *(float *)(data + 24);
dataStruct->y = *(float *)(data + 28);
dataStruct->XSpeed = *(float *)(data + 32);
dataStruct->YSpeed = *(float *)(data + 36);
dataStruct->punchX = *(int *)(data + 44);
dataStruct->punchY = *(int *)(data + 48);
return dataStruct;
}
void SendPacketRaw(int a1, std::vector<BYTE> packetData, size_t packetDataSize, void *a4, ENetPeer *peer, int packetFlag)
{
ENetPacket *p;
if (peer) // check if we have it setup
{
if (a1 == 4 && *((BYTE *)&packetData[12]) & 8)
{
p = enet_packet_create(0, packetDataSize + *((DWORD *)&packetData[13]) + 5, packetFlag);
int four = 4;
memcpy(p->data, &four, 4);
memcpy((char *)p->data + 4, &packetData[0], packetDataSize);
memcpy((char *)p->data + packetDataSize + 4, a4, *((DWORD *)&packetData[13]));
enet_peer_send(peer, 0, p);
}
else
{
p = enet_packet_create(0, packetDataSize + 5, packetFlag);
memcpy(p->data, &a1, 4);
memcpy((char *)p->data + 4, &packetData[0], packetDataSize);
enet_peer_send(peer, 0, p);
}
}
}
调用此函数后
void Nothing(ENetPeer *peer, int x, int y)
{
PlayerMoving data;
data.netID = pinfo(peer)->netID;
data.packetType = 0x8;
data.plantingTree = 0;
data.netID = -1;
data.x = x;
data.y = y;
data.punchX = x;
data.punchY = y;
SendPacketRaw(4, packPlayerMoving(&data), 56, 0, peer, ENET_PACKET_FLAG_RELIABLE);
}
导致分段错误
PlayerMoving *pMov = unpackPlayerMoving(tankUpdatePacket);
if (pMov->plantingTree == 18) {
OnPunch(pMov->punchX, pMov->punchY, world, peer, server);
}
else if (pMov->plantingTree == 32) {
onWrench(world, pMov->punchX, pMov->punchY, peer);
}
else
{
OnPlace(pMov->punchX, pMov->punchY, pMov->plantingTree, world, peer, server); //here it show segmentation fault
}
delete pMov;
我遇到了分段错误,所以我决定使用 valgrind 来查看发生了什么 然后我在 SendPacketRaw 中看到了分段错误,但我真的不知道为什么会发生关于如何解决此问题的任何想法?
这就是 valgrind 给我的东西
==38843== Conditional jump or move depends on uninitialised value(s)
==38843== at 0x1189CF: SendPacketRaw(int, std::vector<unsigned char, std::allocator<unsigned char> >, unsigned long, void*, _ENetPeer*, int) (utils.cpp:152)
==38843== by 0x11E327: Nothing(_ENetPeer*, int, int) (worlds.cpp:405)
==38843== by 0x120B6A: Events::Recieve(_ENetHost*, _ENetPacket*, _ENetPeer*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (events.cpp:342)
==38843== by 0x123D7A: Run() (main.cpp:62)
==38843== by 0x123E24: main (main.cpp:87)
==38843==
==38843== Conditional jump or move depends on uninitialised value(s)
==38843== at 0x145119: enet_packet_create (in /home/cmd/Desktop/PRC++/server)
==38843== by 0x118A16: SendPacketRaw(int, std::vector<unsigned char, std::allocator<unsigned char> >, unsigned long, void*, _ENetPeer*, int) (utils.cpp:154)
==38843== by 0x11E327: Nothing(_ENetPeer*, int, int) (worlds.cpp:405)
==38843== by 0x120B6A: Events::Recieve(_ENetHost*, _ENetPacket*, _ENetPeer*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (events.cpp:342)
==38843== by 0x123D7A: Run() (main.cpp:62)
==38843== by 0x123E24: main (main.cpp:87)
==38843==
==38843== Conditional jump or move depends on uninitialised value(s)
==38843== at 0x483B7A0: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==38843== by 0x14C8D8: enet_malloc (in /home/cmd/Desktop/PRC++/server)
==38843== by 0x145134: enet_packet_create (in /home/cmd/Desktop/PRC++/server)
==38843== by 0x118A16: SendPacketRaw(int, std::vector<unsigned char, std::allocator<unsigned char> >, unsigned long, void*, _ENetPeer*, int) (utils.cpp:154)
==38843== by 0x11E327: Nothing(_ENetPeer*, int, int) (worlds.cpp:405)
==38843== by 0x120B6A: Events::Recieve(_ENetHost*, _ENetPacket*, _ENetPeer*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (events.cpp:342)
==38843== by 0x123D7A: Run() (main.cpp:62)
==38843== by 0x123E24: main (main.cpp:87)
==38843==
==38843== Conditional jump or move depends on uninitialised value(s)
==38843== at 0x48429FA: memmove (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==38843== by 0x118A98: SendPacketRaw(int, std::vector<unsigned char, std::allocator<unsigned char> >, unsigned long, void*, _ENetPeer*, int) (utils.cpp:158)
==38843== by 0x11E327: Nothing(_ENetPeer*, int, int) (worlds.cpp:405)
==38843== by 0x120B6A: Events::Recieve(_ENetHost*, _ENetPacket*, _ENetPeer*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (events.cpp:342)
==38843== by 0x123D7A: Run() (main.cpp:62)
==38843== by 0x123E24: main (main.cpp:87)
==38843==
==38843== Conditional jump or move depends on uninitialised value(s)
==38843== at 0x4842BA1: memmove (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==38843== by 0x118A98: SendPacketRaw(int, std::vector<unsigned char, std::allocator<unsigned char> >, unsigned long, void*, _ENetPeer*, int) (utils.cpp:158)
==38843== by 0x11E327: Nothing(_ENetPeer*, int, int) (worlds.cpp:405)
==38843== by 0x120B6A: Events::Recieve(_ENetHost*, _ENetPacket*, _ENetPeer*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (events.cpp:342)
==38843== by 0x123D7A: Run() (main.cpp:62)
==38843== by 0x123E24: main (main.cpp:87)
==38843==
==38843== Conditional jump or move depends on uninitialised value(s)
==38843== at 0x4842B0E: memmove (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==38843== by 0x118A98: SendPacketRaw(int, std::vector<unsigned char, std::allocator<unsigned char> >, unsigned long, void*, _ENetPeer*, int) (utils.cpp:158)
==38843== by 0x11E327: Nothing(_ENetPeer*, int, int) (worlds.cpp:405)
==38843== by 0x120B6A: Events::Recieve(_ENetHost*, _ENetPacket*, _ENetPeer*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (events.cpp:342)
==38843== by 0x123D7A: Run() (main.cpp:62)
==38843== by 0x123E24: main (main.cpp:87)
==38843==
==38843== Invalid read of size 2
==38843== at 0x4842B30: memmove (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==38843== by 0x118A98: SendPacketRaw(int, std::vector<unsigned char, std::allocator<unsigned char> >, unsigned long, void*, _ENetPeer*, int) (utils.cpp:158)
==38843== by 0x11E327: Nothing(_ENetPeer*, int, int) (worlds.cpp:405)
==38843== by 0x120B6A: Events::Recieve(_ENetHost*, _ENetPacket*, _ENetPeer*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (events.cpp:342)
==38843== by 0x123D7A: Run() (main.cpp:62)
==38843== by 0x123E24: main (main.cpp:87)
==38843== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==38843==
==38843==
==38843== Process terminating with default action of signal 11 (SIGSEGV)
==38843== Access not within mapped region at address 0x0
==38843== at 0x4842B30: memmove (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==38843== by 0x118A98: SendPacketRaw(int, std::vector<unsigned char, std::allocator<unsigned char> >, unsigned long, void*, _ENetPeer*, int) (utils.cpp:158)
==38843== by 0x11E327: Nothing(_ENetPeer*, int, int) (worlds.cpp:405)
==38843== by 0x120B6A: Events::Recieve(_ENetHost*, _ENetPacket*, _ENetPeer*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (events.cpp:342)
==38843== by 0x123D7A: Run() (main.cpp:62)
==38843== by 0x123E24: main (main.cpp:87)
==38843== If you believe this happened as a result of a stack
==38843== overflow in your program's main thread (unlikely but
==38843== possible), you can try to increase the size of the
==38843== main thread stack using the --main-stacksize= flag.
==38843== The main thread stack size used in this run was 8388608.
==38843==
==38843== HEAP SUMMARY:
==38843== in use at exit: 11,984,361 bytes in 22,878 blocks
==38843== total heap usage: 93,823 allocs, 70,945 frees, 29,828,594 bytes allocated
==38843==
==38843== LEAK SUMMARY:
==38843== definitely lost: 928 bytes in 3 blocks
==38843== indirectly lost: 4,940 bytes in 16 blocks
==38843== possibly lost: 224 bytes in 2 blocks
==38843== still reachable: 11,978,269 bytes in 22,857 blocks
==38843== suppressed: 0 bytes in 0 blocks
==38843== Rerun with --leak-check=full to see details of leaked memory
==38843==
==38843== Use --track-origins=yes to see where uninitialised values come from
==38843== For lists of detected and suppressed errors, rerun with: -s
==38843== ERROR SUMMARY: 36605 errors from 14 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
您致电:
SendPacketRaw(4, packPlayerMoving(&data), 56, 0, peer, ENET_PACKET_FLAG_RELIABLE);
//^^
所以第四个参数void *a4
就是0
.
因此这一行从 NULL
指针读取:
memcpy((char *)p->data + packetDataSize + 4, a4, *((DWORD *)&packetData[13]));