结构体内的结构体是如何对齐的
本帖最后由 lgouc 于 2012-11-23 19:46:39 编辑 下面代码:
#pragma pack(4)
struct s1
{
char a;
long b;
};
#pragma pack()
#pragma pack(2)
struct s2
{
char c;
struct s1 st1;
};
#pragma pack()
#pragma pack(2)
struct s3
{
char a;
long b;
};
#pragma pack()
#pragma pack(4)
struct s4
{
char c;
struct s3 st3;
};
#pragma pack()
为什么结构体s4的大小是8呢?结构体内的和本结构体对齐方式不同结构体是如何对齐的呢?望高手指教
[解决办法]
两个原则
直接看图
还有关于这个问题 是没有多少人愿意和你讨论的 真的不值得诶,一个sizeof就搞定了.活用指针,活用结构体吧,骚年。
[解决办法]
这里暂认为编译器处理char占1byte,long占4byte
#pragma pack(2)
struct s3
{
char a; //1byte
long b; //4byte
};
两字节对齐,所以占用6byte
#pragma pack()
#pragma pack(4)
struct s4
{
char c; //1byte
struct s3 st3; //6byte,s3有自己的对齐限制,所以还是占6byte而非5byte
};
四字节对齐,所以占用8byte
#pragma pack()
[解决办法]
我的问题并不在于s4中的s3是不是6个字节.而是既然s4是4字节对齐的,那么s4中的s3应该对齐在4字节处.也就是说s4中的c占一个字节,空出3个字节后存放s3.这种情况下应该是10个字节(如果考虑最长类型的整数倍的话,还有可能再补上2个字节凑成12个字节,虽然感觉有点不妥).
如果s4中的s3还是按照s3的2字节对齐的话,这样便可以解释的通.但是如果这样的话,s2中的s1为什么不是按照s1的四字节对齐呢?
[解决办法]
纠结的目的是什么?
sizeof搞不定?
[解决办法]
其实倒没什么实际的目的.只是想了解已经指定对齐方式的结构体在另一种对齐方式的结构体内是如何对齐的.
[解决办法]
估计只能读源码了。
RTFC。
个人不认为能有哪个标准讲的清,讲的清不见得实现也是这么做的。
[解决办法]
由于#pragma pack(2) 所以 结构体的起始地址 要么是1的N倍,要么是2的N倍。
再由于有long 存在,那么起始地址必然是2的N倍。
那么s3在s4的 起始地址就是2。
s4的内存布局就是 char 空 char 空 long4字节
[解决办法]
具体实现 不同编译器 处理不一样
[解决办法]
#pragma pack(n) 限定结构体的最大对齐字节为n,n可取1、2、4、8、16
s1对齐字节数为4,在s2中,对齐方式限制最大为2,实际字节对齐数=min(4,2)=2
s3的对齐字节数为2,在s4中,对齐方式限制最大为4,实际对齐字节数=min(2,4)=2
[解决办法]
受教学习了~~~~
[解决办法]
VC调试时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!