请问这个怎么对齐的

maxc2010 2012-11-04 11:08:01
struct MM
{
char u;
char v;
int w;
char x;
char y;
int z;
int o;
};


class A1
{
private:

double a;
char c;
MM mm;
int b;
char d;
float e;

};

这个sizeof(A1) 为啥是48,而不是40
...全文
310 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
lm_whales 2013-09-07
  • 打赏
  • 举报
回复
翻了一下,觉得有必要稍微解释一下,是为回复!
lm_whales 2013-09-07
  • 打赏
  • 举报
回复
对齐的原则
1)凑整
2)对齐
3)用户定义类型,先对齐,后参与奏整
4)有些平台可能,每个数据都要凑整后对齐,有些平台可能先凑整后对齐。
关于凑整是这样的,一些长度较小的数据会凑在一起作为整体,然后对齐
比如,相邻的两个char会当作一个双字节,两个char,一个short会当作一个四字节处理,凑出对齐量的整数倍,不足加一,大数据会从头开始对齐,以避免存取耗时或者对齐异常的出现!!这是平台相关的,编译器自己安排的行为!!只怕不是标准!
lm_whales 2013-05-09
  • 打赏
  • 举报
回复
VC6: #pragma pack(1) MM:16,A1:34 #pragma pack(2) MM:16,A1:36 #pragma pack(4) MM:20,A1:44 #pragma pack(8) MM:20,A1:48 #pragma pack(16) MM:20,A1:48
赵4老师 2012-11-07
  • 打赏
  • 举报
回复
VC调试时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。) 不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
User64 2012-11-06
  • 打赏
  • 举报
回复
[quote=引用 16 楼 User64 的回复:] 本来char c后是按照20字节对齐的,但是编译器默认的是8,超过8的就按照8字节对齐,小于的就按照较小的那个对齐
User64 2012-11-06
  • 打赏
  • 举报
回复
struct MM { char u; //1 //标记为起始地址 char v; //2 int w; //5 char x; //9 char y; //10 int z; //13 int o; //17 }; //共20字节 class A1 { private: double a; //1 char c; //9 MM mm; //17 主要是这里,char c后填充的是7个字节 int b; //37 char d; //41 float e; //45 };
wizard_tiger 2012-11-06
  • 打赏
  • 举报
回复
引用 12 楼 User64 的回复:
编译器默认以8字节对齐,当成员变量最大的字节数超过8时就按照8字节对齐,小于的话就按照最大的那个对齐
++
whizer 2012-11-05
  • 打赏
  • 举报
回复
引用 3 楼 maxc2010 的回复:
a: 8 c+u+v+w: 8 x+y+z: 8 o+b:8 d+e:8 总共: 8*5 = 40 这样理解为啥不对呢?
结构体里面的结构体要四字节对齐放置.
User64 2012-11-05
  • 打赏
  • 举报
回复
引用 12 楼 User64 的回复:
编译器默认以8字节对齐,当成员变量最大的字节数超过8时就按照8字节对齐,小于的话就按照最大的那个对齐
主要是A1::c也按照8字节对齐的
User64 2012-11-05
  • 打赏
  • 举报
回复
编译器默认以8字节对齐,当成员变量最大的字节数超过8时就按照8字节对齐,小于的话就按照最大的那个对齐
toadzw 2012-11-05
  • 打赏
  • 举报
回复
struct MM { char u; char v; double w; char x; char y; int z; int o; }; struct A1 { double a; char c; struct MM mm; int b; char d; float e; }; struct A2 { double a; char c; }; struct A3 { double a; char c; struct MM mm; }; struct A4 { double a; char c; struct MM mm; int b; }; struct A5 { double a; char c; struct MM mm; int b; char d; }; A1:64 A2:16 A3:48 A4:56 A5:56 请按任意键继续. . .
toadzw 2012-11-05
  • 打赏
  • 举报
回复
struct MM { char u; char v; int w; char x; char y; int z; int o; }; struct A1 { double a; char c; struct MM mm; int b; char d; float e; }; struct A2 { double a; char c; }; struct A3 { double a; char c; struct MM mm; }; struct A4 { double a; char c; struct MM mm; int b; }; struct A5 { double a; char c; struct MM mm; int b; char d; }; A1:48 A2:16 A3:32 A4:40 A5:40 请按任意键继续. . .
olderma 2012-11-05
  • 打赏
  • 举报
回复
class A1
    {
    private:

        double a;  // 8字符
        char c;//2
        MM mm;//20
        int b;//8
        char d;//2
        float e;//8

    };
olderma 2012-11-05
  • 打赏
  • 举报
回复
http://blog.sina.com.cn/s/blog_48d8ae76010002g4.html 这篇文章讲的很详细
swordtan 2012-11-05
  • 打赏
  • 举报
回复
引用 1 楼 xiaoqin515515 的回复:
楼主是不是把double当成4字符了. sizeof(struct MM) = 20; class A1 { private: double a; // 8字符 char c; MM mm; int b; char d; float……
++
JiMoKuangXiangQu 2012-11-04
  • 打赏
  • 举报
回复
google/百度字节对齐. 其实字节对齐的细节和具体编译器实现相关,但一般而言,满足四个准则: 1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除; 2) 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节; 3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节; 4) 数据成员、结构体和类的有效对齐值: 如果指定对齐值(在VS编译器用#pragma pack(n)语法指定)小于自身对齐值,使用自身对齐值; 否则,取自身对齐值和指定对齐值中小的那个值。
maxc2010 2012-11-04
  • 打赏
  • 举报
回复
a: 8 c+u+v+w: 8 x+y+z: 8 o+b:8 d+e:8 总共: 8*5 = 40 这样理解为啥不对呢?
armsword 2012-11-04
  • 打赏
  • 举报
回复
因为对齐之后,应该是内部最大成员的的整数倍。
慧钦 2012-11-04
  • 打赏
  • 举报
回复
楼主是不是把double当成4字符了. sizeof(struct MM) = 20; class A1 { private: double a; // 8字符 char c; MM mm; int b; char d; float e; }; 所以8+1(+3)+20+4+1(+3)+4 = 44,最大类型为double=8字符,填充至8的倍数,也就是48了
qin_pp 2012-11-04
  • 打赏
  • 举报
回复
google/百度字节对齐. 其实字节对齐的细节和具体编译器实现相关,但一般而言,满足四个准则: 1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除; 2) 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节; 3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节; 4) 数据成员、结构体和类的有效对齐值: 如果指定对齐值(在VS编译器用#pragma pack(n)语法指定)小于自身对齐值,使用自身对齐值; 否则,取自身对齐值和指定对齐值中小的那个值。 引用楼上的,同样的疑惑,学习一下!

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧