字节对齐详解

    以前一直以为字节对齐是个症结,平时的实际应用中接触的太多了,若是不去弄懂它,感受它就是一个短板,因而着手开始研究了它,今天在公司的例行讲解中又讲到了这个,回来想一想仍是整理下,算是给一个总结概括。
    首先我不得不提一个预编译命令 #pragma pack(),为了更好的切入主题我暂且只关心#pragma pack(n)这种设置当前字节对齐值为n的用法,有一点必须注意,n只有等于1,2,4,8,16才是有效值,其它的设置都是无效的。
    下面,我从结构体入手,先看一段代码布局

#include <stdio.h>

#pragma pack (1)
struct stu1
{
	int b;
};
#pragma pack ()

struct stu2
{
	char a;
	struct stu1 b;

};

int main()
{
	printf("sizeof(struct stu1)=%d\nsizeof(struct stu2)=%d\n", sizeof(struct stu1),sizeof(struct stu2));
	return 1;
}

     运行结果
    
    对于结构体stu1来讲,它的字节对齐是1,是否是以为很奇怪,一般咱们查资料的时候都会说结构体的字节对齐值取的是结构体中全部类型中字节对齐值最大的那个,那若是这样的话,stu1难道不该该是4吗?变量a的后面不用补零吗?    
    问题进行到这里,咱们有必要弄懂两个概念: 有效字节对齐值 类型自身字节对其值
    int 型在32位系统上所占字节数为4,字节对齐值为4,即int型自身字节对齐值为4;相似的还有char、double等等;
    struct结构体的自身字节对齐值为结构体中全部类型里自身字节对齐值最大的那个;
    有效字节对齐值,实际上是在最终实际内存操做中字节对齐的值,取的值是系统指定值(或默认值)与类型自身字节对齐值 较小 的那个。如上例经过#pragma pack (1)指定字节对齐值为1,而结构体自身的字节对齐值为4(取int的),因而stu1的有效字节对齐值为1,因此在结构体stu2中,stu1相对于stu2结构体的首地址偏移量(变量a所占的内存大小)除以stu1的有效字节对齐值是整数,符合条件,故而不用在变量a以后补0,结果为5.
    弄清楚了这些概念,那么咱们再回顾一下结构体内存分配的原则:

    1. 结构体内部,每一个变量至关于结构体首地址的偏移量的大小必须是这个变量类型有效字节对齐值的整数倍。    
    2. 结构体自身,结构体分配内存的大小必须是结构体有效字节对齐值的整数倍。
    好了,弄清楚了这些概念,咱们再开始看一段程序,来验证一下这些结论
    
spa

#include <stdio.h>

#pragma pack (2)
struct stu1
{
	char a;
	int b;
};
#pragma pack ()

struct stu2
{
	char a;
	int b;

};

int main()
{
	printf("sizeof(struct stu1)=%d\nsizeof(struct stu2)=%d\n", 
			sizeof(struct stu1),sizeof(struct stu2));
	return 1;
}


    运行结果

    

    分析
       变量                   a        b
       stu1内存布局      *0      ****
code

       stu2内存布局      *000   ****     (*表示a、b的实际值,0表示为了字节对齐补的0值内存

相关文章
相关标签/搜索