小Bug大麻烦

上周把服务器端的大体框架做出来了,这周开始用各种消息做测试。
前面急着写结构,曾出了一个在Debug版本时出的错误也没找到原因,就直接改成Release版本直接做了。
可这周为了测试各种消息的状态,需要用到调试代码,就改了过来,本来以为挺简单的一个原因,却搞了一个上午:(。
先看代码:


 char* sdata=new char[2048];   //声明大的内存块接收数据
 memset(sdata,0,2048);

 sockaddr_in sender;     //发送者的socket
 int dwsender=sizeof(sender);

 int index=0,DataLenght=0;
 MSGPackage m;      //接收的信息对象
 
 //接收数据到临时数据区
 recvfrom(UDPClient,sdata,2048,0,(sockaddr *)&sender,&dwsender);
 
 //从临时数据区分段复制到数据报中
 memcpy((BYTE*)&(m.HeadIndex),sdata+index,sizeof(m.HeadIndex));
 index+=sizeof(m.HeadIndex);
 memcpy((BYTE*)&(m.MsgType),sdata+index,sizeof(m.MsgType));
 index+=sizeof(m.MsgType);
 memcpy((BYTE*)&(m.Encrypt),sdata+index,sizeof(m.Encrypt));
 index+=sizeof(m.Encrypt);
 memcpy((BYTE*)&(m.CRC),sdata+index,sizeof(m.CRC));
 index+=sizeof(m.CRC);
 memcpy((BYTE*)&(m.DataLen),sdata+index,sizeof(m.DataLen));
 index+=sizeof(m.DataLen);
 memcpy((BYTE*)&(m.Res),sdata+index,sizeof(m.Res));
 index+=sizeof(m.Res);

 m.data=new char[m.DataLen];                                      
 DataLenght=m.DataLen;
 memset(m.data,0,DataLenght);
 strcpy(m.data,sdata+index);
 
 //把数据包和发送地址存到接收队列中

 CMSG msg;
 msg.SetMSG(m,sender);

 m_g_ReciveCs.Lock();
 m_ReciveList.AddTail(msg);
 m_g_ReciveCs.Unlock();
 
 //删除临时数据
 delete [] m.data;
 m.data=NULL;
 delete [] sdata;
 sdata=NULL;

在接收过程中,申请大的内存块,把数据一次接收下来,然后再一块儿一块儿的复制数据包对象中,
再把数据包对象和发送人的地址一块儿放到接收队列中,最后把临时数据删除。

结果就是在删除临时数据m.data这个字符串指针时出错了,查来查去,最把问题搞清楚了。
strcpy复制时会从源数据的开始复制数据直接遇到NULL时终止,而在客户端,sdata的长度要比正确的值多了
一个m.DataLen,结果strcpy后,m.data的数据比分配的长度多,也就是复制越界了,所以改成Debug版本后
就出错了。另外即使数据长度没加长也是为有错误,因为在复制字符时会有一个终止符("/n")产生,所以在分配时应该多加一个,改成:
 m.data=new char[m.DataLen+1];    
这样就不会出错了。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页