结构体中慎用指针

来源:互联网 发布:爰奇艺软件 编辑:程序博客网 时间:2024/06/06 00:35

转载请注明出处

作者:小马


今天写一个基于TCP/IP的数据包发送程序时, 遇到一个问题, 我发送了一个数据包过去, 服务端可以接收到,但接收到的数据长度小于我实际传送的数据长度. 这个bug调了很久, 开始还认为是服务器端的程序问题, 最终发现是栽在了指针上面.

 

发送数据包的包格式形如下面的定义:

[cpp] view plaincopy
  1. typedef struct _TestStruct  
  2.   
  3. {  
  4.   
  5.          char testA[5];  
  6.   
  7.          char *pTest;  
  8.   
  9.          char testC[4];  
  10.   
  11. }TestStruct_s;  


 

因为,pTest域的大小是可变的, 需要动态分配. 所以我把它置成指针. 然后我对数据包赋值

[cpp] view plaincopy
  1. TestStruct_s testData;  
  2.   
  3. memcpy(testData.testA, "abcde", 5);  
  4.   
  5. testData.pTest = (char *)malloc(sizeof(char)*3);  
  6.   
  7. memcpy(testData.pTest, "fgh", 3);  
  8.   
  9. memcpy(testData.testC, "ijkl", 4);  


 

接着调用一个socket发送函数把这个包发送出去, 该函数接收两个参数, 一个要发送的字符串缓冲区,一个是缓冲区长度. 所以我先把组好的数据包复制到一个临时缓冲区里.

 

[cpp] view plaincopy
  1. <span style="color:#000000;"></span>   
[cpp] view plaincopy
  1. <span style="color:#000000;">char sendBuffer[1024] = {0};  
  2.   
  3. char sendLen = 12;  
  4.   
  5. memcpy(sendBuffer, &testData, sendLen);</span> //这一步出现了致命的错误.   


我想当然的以为sendBuffer应该是”abcdefghijkl”了, 所以我调用socket_send函数发送数据到服务器.

socket_send(sendBuffer, sendLen);

 

相信高手应该已经看出来我的问题在哪里了. 因为memcpy是复制连续的内存, 但是testData的数据并不是连续的, 因为pTest域是

testData.pTest = (char *)malloc(sizeof(char)*3)动态分配的.

单步跟一下内存如下图所示:

 

0x0012fb80是sendBuffer的内存地址, 可以看出, 到第三个CC后面的00,sendBuffer就已经束了, 因为字符串是以0x00结尾的, memcpy在执行的时候, 只复制到这里就结束了.

原创粉丝点击