大话sizeOf()

大家都知道,sizeof()可以用来计算某个类,结构体,变量的占用空间大小,返回字节数,但是可能有些筒子们只知其一不知其二,最近看了几篇文章,搞懂了一些,和大家分享一下。

一,对齐

今天我们要讨论的问题和对其有很大的关联,那什么是对齐呢?以前在汇编课上学过align命令:align num,num必须是2的整数次幂,其意义是告诉汇编程序,本伪指令下面的内存变量必须从下一个能被Num整除的地址开始分配。
什么是对齐呢?通俗一点就是现代计算机的内存地址在理论上讲是可以任意访问任何一块地址,但实际上并不是,实际的合法访问地址往往都是有要求的,比如必须以4的整数倍地址号开始等等,这就要求数据必须按照既定的规则在内存上排序,而不是按顺序紧接着上一个数据排序。
什么要这样设计?各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。比如有些架构的CPU在访问一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保证字节对齐.其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。显然在读取效率上下降很多。
二,字节对齐对程序的直接影响
struct A
 {
      int a;
      char b;
      short c;
 };
 struct B
 {
      char b;
      int a;
      short c;
 };

结果是:
sizeof(strcut A)值为8
sizeof(struct B)的值却是12
按理说两者结果都应该是7为什么会出现这样的结果呢?这就是字节对齐引起的结果,那又是怎么对齐的呢?
三,对齐方式

  • 数据类型自身的对齐值
    -char:1B short:2B int float double:4B
  • 结构体或者类的自身对齐值
    -其成员中自身对齐值最大的那个值
  • 指定对齐值
    -pragma pack (value)时的指定对齐值value
  • 数据成员、结构体和类的有效对齐值
    -自身对齐值和指定对齐值中小的那个值
    有效对齐值是最终决定存放地址的值,有效对齐值为N,即“对齐在N上”,也就是“存放地址%N=0”。而数据结构中的变量都是按顺序存放的,第一个数据变量的起始地址就是数据结构的起始地址。结构体的成员变量要对齐排放,结构体本身也要根据自身的有效对齐值圆整(就是结构体成员变量占用总长度需要是对结构体有效对齐值的整数倍)。

    四,回顾刚才的两个例子
    假设制定对齐值为默认4B,存储都从0x0000开始
    先看第一个:

struct A
 {
      int a;
      char b;
      short c;
 };

1,数据结构自身对齐值:a:4,b:1,c:2
2,A自身对齐值:4
3,指定对齐值:4
4,有效对齐值:a:4,b:1,c:2,A:4
存放地址:
a:0x0000~0x0003,b:0x0004,(0x0005空着)c:0x0006~0x0007
圆整:
A有效对齐值是4,则占用地址不能使0x0000~0x0007,而是0x0000~0x0008。
所以sizeof(A)=8.
在看第二个:
struct B
{
char b;
int a;
short c;
};

1,数据结构自身对齐值:a:4,b:1,c:2
2,2,A自身对齐值:4
3,指定对齐值:4
4,有效对齐值:a:4,b:1,c:2,A:4
存放地址:
a:0x0000,(0x0001~0x0003空着)b:0x0004~0x0007,c:0x0008~0x0009
圆整:
A有效对齐值是4,则占用地址不能使0x0000~0x0009,而是0x0000~0x00012。所以sizeof(A)=12.
参考自http://blog.csdn.net/hxg130435477/article/details/4018479

你可能感兴趣的:(编程,汇编,计算机组成)