C++内存对齐

在C语言和C++语言中相信很多人都有使用过sizeof(),这个帖子主要偏向于交流获取class和struct的字节数时候的问题。


      我使用的是windows 7的32位OS 和 VS2010的旗舰版


      先来一些正常的


[cpp]  view plain copy
  1. struct testS  
  2. {  
  3.     bool a;  
  4.     char b;  
  5.     short c;  
  6.     int d;  
  7.   
  8. };  
  9.   
  10. class testC  
  11. {  
  12. private :  
  13.     int a;  
  14. public:  
  15.     float b;  
  16.     char c;  
  17.     bool d;  
  18.     short e;  
  19.     void get(int temp)  
  20.     {  
  21.         int cc;  
  22.     }  
  23. };  
  24.   
  25. int main()  
  26. {  
  27.     cout<<"sizeof(testS):"<<sizeof(testS)<<endl;  
  28.     cout<<"sizeof(testC):"<<sizeof(testC)<<endl;  
  29.     getchar();  
  30.     return 0;  
  31. }  


这个时候相信大家都能想到输出的结果是




     从这里我们可以看到我们用sizeof()取struct和class的字节的时候只有他们的成员变量才算进去的,方法及其内部的变量是不算的。当然了,一个空类是默认1字节的。


     接下来我们来做一些“不正常”的

[cpp]  view plain copy
  1. struct testS  
  2. {  
  3.     char b;  
  4.     short c;  
  5.     int d;  
  6.     bool a;  
  7. };  
  8.   
  9. class testC  
  10. {  
  11. private :  
  12.     int a;  
  13. public:  
  14.     float b;  
  15.     char c;  
  16.     short e;  
  17.     bool d;  
  18.     void get(int temp)  
  19.     {  
  20.         int cc;  
  21.     }  
  22. };  
  23.   
  24. int main()  
  25. {  
  26.     cout<<"sizeof(testS):"<<sizeof(testS)<<endl;  
  27.     cout<<"sizeof(testC):"<<sizeof(testC)<<endl;  
  28.     getchar();  
  29.     return 0;  
  30. }  

     我们这次只是调换了一下成员变量的位置,然后我们再次运行一下查看结果。




     很奇怪的结果,这个的运行结果不是我们正常想象的结果。这是为什么呢?

     原来struct和class中为变量分配空间是以结构中最长数据元素为对齐方式的。

     例如之前我们看过的例子(class 和 struct一样我们就以struct为例):

testS 一:


变量          分配空间(字节)          占用空间(字节)          起始地址

      bool a                  4                                  1                            1

       char b                 0                                  1                            2

        short c                0                                  2                            3

         int d                   4                                  4                            5

通过这个我们可以看到分配空间是以最高的int为主的,如果可以填充的话就填充。sizeof(testS) = 8


testS  二:

变量          分配空间(字节)          占用空间(字节)          起始地址

      char b                  4                                  1                            1

       short c                 0                                  2                            2

        int d                    4                                  4                            5

       bool a                   4                                  1                            9

比之前我们只是将变量a调换到了最后,但是整个空间分配就和之前的不一样了。sizeof(testS) = 12

通过这两次的图表对比大家可以了解是什么原因导致这个结果了吧。。

内存对齐的规则:

1、  对于结构的各个成员,第一个成员位于偏移为0的位置,以后每个数据成员的偏移量必须是min(#pragma pack()指定的数,这个数据成员的自身长度) 的倍数。

2、  在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行对齐。

 

#pragma pack(n) 表示设置为n字节对齐。 VC6默认8字节对齐



在判断如何对齐的时候,我们可以根据偏移量和自身类型的sizeof的倍数来决定例如:

[cpp]  view plain copy
  1. struct testS  
  2. {  
  3.     char b;  
  4.     int c;  
  5.     double d;  
  6. };  
在给char b申请内存时偏移量为0,是sizeof(char)的倍数直接分配。

在给int c申请内存时偏移量为1,不是sizeof(int)的倍数所以要填充3个字节让偏移量达到4成为sizeof(int)的倍数然后为其分配内存。

在给double d申请内存时偏移量为8时sizeof(double)的倍数,直接分配。

所以最后sizeof(testS)的结果是16


[cpp]  view plain copy
  1. struct testS  
  2. {  
  3.     int c;  
  4.     char b;  
  5. };  

在testS中按照上面描述的方法进行分配内存。

分配int c时偏移量为0直接分配

分配char b时偏移量为4直接分配

那么sizeof(testS)就是5了吗?    结果显然不是的··········

这只是完成了数据成员的内存对齐,还没有做结构本身的内存对齐。按照结构本身的对齐规则来说,我们要取出所有成员和#pragma pack指定的数值中较小的一个得倍数来对齐结构。所以sizeof(testS)的结果是8

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值