微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

来自导致段错误的函数的 C++ 错误

如何解决来自导致段错误的函数的 C++ 错误

你好,我有这个函数,我试图从中获取

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,p);
        }
        else
        {
            p = enet_packet_create(0,packetDataSize + 5,packetFlag);
            memcpy(p->data,&a1,packetDataSize);
            enet_peer_send(peer,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,peer,ENET_PACKET_FLAG_RELIABLE);
}

导致分段错误


PlayerMoving *pMov = unpackPlayerMoving(tankUpdatePacket);
if (pMov->plantingTree == 18) {
   OnPunch(pMov->punchX,pMov->punchY,world,server);
}
else if (pMov->plantingTree == 32) {
    onWrench(world,pMov->punchX,peer);
}
else
{
    OnPlace(pMov->punchX,pMov->plantingTree,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*,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,int) (utils.cpp:154)
==38843==    by 0x11E327: nothing(_ENetPeer*,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::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,int) (utils.cpp:158)
==38843==    by 0x11E327: nothing(_ENetPeer*,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::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::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::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::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,peer,ENET_PACKET_FLAG_RELIABLE);
                                           //^^

所以第四个参数 void *a40

所以这一行从 NULL 指针读取:

memcpy((char *)p->data + packetDataSize + 4,a4,*((DWORD *)&packetData[13]));

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。