Chinaunix首页 | 论坛 | 博客
  • 博客访问: 119103
  • 博文数量: 23
  • 博客积分: 269
  • 博客等级: 入伍新兵
  • 技术积分: 165
  • 用 户 组: 普通用户
  • 注册时间: 2012-01-22 10:38
文章分类

全部博文(23)

文章存档

2014年(1)

2012年(22)

分类: C/C++

2012-06-21 14:05:27

c/c++字节对齐,跟操作系统位数以及编译器都有关系,本文主要讲3种情况,linux32 linux64,windows32/64,若有不正确之处,欢迎指正!

下面就以给结构体分配内存的方式,分析结构体所占用的字节数。
在linux 下,结构体字节对齐,遵循以下几个原则:(g++编译)
1.数据的相对内存地址,必须是其占用字节数的整数倍,32位操作linux系统除外。
  比如:

点击(此处)折叠或打开

  1. struct A
  2. {
  3.     int32_t a;
  4.     double b;
  5. }
   a的相对地址为0,a要占用的地址大小为4,0为4的0倍,是整数倍,
   b的相对地址是4或者8,这个需要看操作系统的位数,于是引出第二条原则。
2.linux 32位操作系统,当数据占用字节大于4位时,即保证相对地址为操作系统字节数整数倍即可。
   对于以上例子中,如果是在linux 32位操作系统,32位为4字节,所以b的相对地址就是4,
   如果是linux 64位操作系统,那么b的相对地址就是8.
   加上自身的字节数,那么sizeof(struct A)= 12 或者 16.

3.在给结构体的变量非配内存时,总是以结构体中占用字节数最大的元素为单位分配内存,32位操作系统除外。32位操作系统,每次分配的内存数,不超过4个字节。

   如结构体struct A 中,系统计算要给A分配的内存时,结构体最大元素占用字节数为8
   linux 32位系统:
      首先计算时,是增加4个字节,接着计算b需要的内存时,因为前面分配的4个字节,已
   经全部用于元素a,则需要重新分配4个字节,而4个字节又不能存下b,所以再增加4个字节,
   也就是12个字节。
   linux 64为系统:
      首先是增加8个字节,用于存贮a,计算b需要占用的内存时,减去a要占用的4个字节,也
   就是剩下4个字节用于存储b,而b需要8个字节,所以需要重新分配8个字节,加起来就是16
   个字节,而根据原则1,b的地址需要是8的倍数,也就是在分配的16个字节中,第8个字节开
   始,用于存贮b。


4.对于windows操作系统,使用vs编译器,则完全没有位的概念,使用以上各条规则,没有位的限制。即结构体struct A在windows中,其所占用的字节数跟linux 64位系统一样,都是16个字节。


  
阅读(6353) | 评论(3) | 转发(3) |
给主人留下些什么吧!~~

Aquester2012-06-25 17:05:01

zxqcreazy: 看了你的博客,我的理解是,-mno-aligan-double 跟-maligan-double 两个选项是gcc中设定double对齐字节数的编译参数,
x86-32下默认是带 -mno-aligan-double参数.....
是的,一般人容易产生的误解是取sizeof的值,实际并不是这样。

zxqcreazy2012-06-25 16:37:28

Aquester: 可以参考一下这个:http://blog.chinaunix.net/uid-20682147-id-3234270.html.....
看了你的博客,我的理解是,-mno-aligan-double 跟-maligan-double 两个选项是gcc中设定double对齐字节数的编译参数,
x86-32下默认是带 -mno-aligan-double参数的,就是4字节对齐,
x86-64下默认是带-maligan-double参数的,就是8字节对齐,
我这里的描述,比较一般性,而且有些特殊情况没有表述到,比如带着种
编译参数,或者带#pragma pack(n) 的时候。不知道理解是否正确。

Aquester2012-06-22 13:47:09

可以参考一下这个:http://blog.chinaunix.net/uid-20682147-id-3234270.html