#pragma pack(1)
struct testpack{
char chain;
WORD serial;
DWORD serialnumber;
};
#pragma pack()
char cbuffer[200];
testpack * mypack = new testpack();
mypack->chain = 'C';
mypack->serial = 0;
mypack->serialnumber = 12288;
内存中testpack本来是 0x43 0x0000 0x00003000
memset(cbuffer, 0x00, 200);
memcpy(cbuffer, mypack,7 );
内存copy之后为什么是 0x430000003000 少了一个字节了!求解!
18 个解决方案
#1
早上起来先顶一个,坐等高手解答。
#2
你数错了吧,无图无真相
#3
DWORD 里面是反着存储的应该是00 30 00 00
#4
其实这个问题是我在做socket连接时候发送出现的,因为send要转换成char发送,只要将结构体memcpy到char缓冲区就会出现这个问题。继续求教高手解答。
#5
应该是你自己数错了。
struct结构体,按照对齐原则,0x43之后应该会多出一个字节,我估计你没算进去,否则你应该是
memcpy(cbuffer, mypack,8 );
struct结构体,按照对齐原则,0x43之后应该会多出一个字节,我估计你没算进去,否则你应该是
memcpy(cbuffer, mypack,8 );
#6
因为你要用socket传输,建议你在给struct实例赋值的时候,先对其做初始化。我的测试代码如下:
struct testpack{
char chain;
WORD serial;
DWORD serialnumber;
};
printf("size:%d,%d,%d,%d\n", sizeof(char), sizeof(WORD),sizeof(DWORD), sizeof(testpack));
char cbuffer[200];
testpack * mypack1 = new testpack();
memset(mypack1, 0x00, sizeof(testpack));
mypack1->chain = 'C';
mypack1->serial = 0;
mypack1->serialnumber = 12288;
//内存中testpack本来是 0x43 0x0000 0x00003000
testpack* mypack2 = new testpack();
memset(cbuffer, 0x00, 200);
memcpy(cbuffer, mypack1, 8);
memcpy(mypack2, cbuffer, 8);
delete mypack1;
delete mypack2;
#7
最后我再说一句:
你直接将一个struct通过socket发送出去,难道你在接收方再copy给同样地struct?这样做可不是什么好办法。
我的建议是,就算你在接收端要恢复成struct,也应该自定义一套规则,通过json字符串格式,进行序列化和反序列化。
你直接将一个struct通过socket发送出去,难道你在接收方再copy给同样地struct?这样做可不是什么好办法。
我的建议是,就算你在接收端要恢复成struct,也应该自定义一套规则,通过json字符串格式,进行序列化和反序列化。
#8
c++一般是小字节序,DWORD的12288的十六进制是0x00003000,但在内存中因小字节序低字节在低地址高字节在高地址,所以实际存储的字节顺序是00300000,刚好反过来的;WORD serial也是如此,只不过因为值是0看不出反过来了而已。
所以最终拷贝的是0x43000000300000,没有少字节。
所以最终拷贝的是0x43000000300000,没有少字节。
#9
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……
对学习编程者的忠告:
多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程!
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步Debug版对应汇编一行!
单步Debug版对应汇编千行不如单步Release版对应汇编一行!
不会单步Release版对应汇编?在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有,然后在IDE中运行。(一般人我不告诉他! )
VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
对学习编程者的忠告:
多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程!
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步Debug版对应汇编一行!
单步Debug版对应汇编千行不如单步Release版对应汇编一行!
不会单步Release版对应汇编?在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有,然后在IDE中运行。(一般人我不告诉他! )
VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
#10
memcpy(cbuffer, mypack,sizeof(testpack) )
你那样子的做法根本不通用,而且你还字节对其之类的呢
你那样子的做法根本不通用,而且你还字节对其之类的呢
#11
这不是字节对齐的问题,结构定义已经明确1字节对齐,3楼是正解
我觉得问题应该出在传输过程了,少发或者少接
我觉得问题应该出在传输过程了,少发或者少接
#12
不知道有多少前人掉在TCP Socket
send(人多)send(病少)send(财富)
recv(人多病)recv(少财富)
陷阱里面啊!
http://bbs.csdn.net/topics/380167545
建议楼主学会使用抓包软件比如wireshark
#13
之前我居然丢掉了#pragma pack……重新测试了下,以'-'作为结束标志,重新截了俩图:
#14
再上两张图,证明3楼确实是对的……我以前居然没注意到这个问题。
#15
老赵,我暴露出我是菜鸟的事实了,咋办?我们把CSDN黑了吧?
#16
人无完人;完人不是人,是AlphaGo!
#17
ALphaGo不是人……
人无完人;完人不是人,是AlphaGo!
#18
struct结构的问题。
#1
早上起来先顶一个,坐等高手解答。
#2
你数错了吧,无图无真相
#3
DWORD 里面是反着存储的应该是00 30 00 00
#4
其实这个问题是我在做socket连接时候发送出现的,因为send要转换成char发送,只要将结构体memcpy到char缓冲区就会出现这个问题。继续求教高手解答。
#5
应该是你自己数错了。
struct结构体,按照对齐原则,0x43之后应该会多出一个字节,我估计你没算进去,否则你应该是
memcpy(cbuffer, mypack,8 );
struct结构体,按照对齐原则,0x43之后应该会多出一个字节,我估计你没算进去,否则你应该是
memcpy(cbuffer, mypack,8 );
#6
因为你要用socket传输,建议你在给struct实例赋值的时候,先对其做初始化。我的测试代码如下:
struct testpack{
char chain;
WORD serial;
DWORD serialnumber;
};
printf("size:%d,%d,%d,%d\n", sizeof(char), sizeof(WORD),sizeof(DWORD), sizeof(testpack));
char cbuffer[200];
testpack * mypack1 = new testpack();
memset(mypack1, 0x00, sizeof(testpack));
mypack1->chain = 'C';
mypack1->serial = 0;
mypack1->serialnumber = 12288;
//内存中testpack本来是 0x43 0x0000 0x00003000
testpack* mypack2 = new testpack();
memset(cbuffer, 0x00, 200);
memcpy(cbuffer, mypack1, 8);
memcpy(mypack2, cbuffer, 8);
delete mypack1;
delete mypack2;
#7
最后我再说一句:
你直接将一个struct通过socket发送出去,难道你在接收方再copy给同样地struct?这样做可不是什么好办法。
我的建议是,就算你在接收端要恢复成struct,也应该自定义一套规则,通过json字符串格式,进行序列化和反序列化。
你直接将一个struct通过socket发送出去,难道你在接收方再copy给同样地struct?这样做可不是什么好办法。
我的建议是,就算你在接收端要恢复成struct,也应该自定义一套规则,通过json字符串格式,进行序列化和反序列化。
#8
c++一般是小字节序,DWORD的12288的十六进制是0x00003000,但在内存中因小字节序低字节在低地址高字节在高地址,所以实际存储的字节顺序是00300000,刚好反过来的;WORD serial也是如此,只不过因为值是0看不出反过来了而已。
所以最终拷贝的是0x43000000300000,没有少字节。
所以最终拷贝的是0x43000000300000,没有少字节。
#9
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……
对学习编程者的忠告:
多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程!
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步Debug版对应汇编一行!
单步Debug版对应汇编千行不如单步Release版对应汇编一行!
不会单步Release版对应汇编?在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有,然后在IDE中运行。(一般人我不告诉他! )
VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
对学习编程者的忠告:
多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程!
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步Debug版对应汇编一行!
单步Debug版对应汇编千行不如单步Release版对应汇编一行!
不会单步Release版对应汇编?在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有,然后在IDE中运行。(一般人我不告诉他! )
VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
#10
memcpy(cbuffer, mypack,sizeof(testpack) )
你那样子的做法根本不通用,而且你还字节对其之类的呢
你那样子的做法根本不通用,而且你还字节对其之类的呢
#11
这不是字节对齐的问题,结构定义已经明确1字节对齐,3楼是正解
我觉得问题应该出在传输过程了,少发或者少接
我觉得问题应该出在传输过程了,少发或者少接
#12
这不是字节对齐的问题,结构定义已经明确1字节对齐,3楼是正解
我觉得问题应该出在传输过程了,少发或者少接
不知道有多少前人掉在TCP Socket
send(人多)send(病少)send(财富)
recv(人多病)recv(少财富)
陷阱里面啊!
http://bbs.csdn.net/topics/380167545
建议楼主学会使用抓包软件比如wireshark
#13
之前我居然丢掉了#pragma pack……重新测试了下,以'-'作为结束标志,重新截了俩图:
#14
再上两张图,证明3楼确实是对的……我以前居然没注意到这个问题。
#15
老赵,我暴露出我是菜鸟的事实了,咋办?我们把CSDN黑了吧?
这不是字节对齐的问题,结构定义已经明确1字节对齐,3楼是正解
我觉得问题应该出在传输过程了,少发或者少接
不知道有多少前人掉在TCP Socket
send(人多)send(病少)send(财富)
recv(人多病)recv(少财富)
陷阱里面啊!
http://bbs.csdn.net/topics/380167545
建议楼主学会使用抓包软件比如wireshark
#16
人无完人;完人不是人,是AlphaGo!
#17
ALphaGo不是人……
人无完人;完人不是人,是AlphaGo!
#18
struct结构的问题。