现在的位置: 首页 > 综合 > 正文

字节对齐

2013年09月02日 ⁄ 综合 ⁄ 共 1740字 ⁄ 字号 评论关闭

在讨论字节对齐之前我们先来看一个计算占用内存题目

#include <iostream.h>

#pragma pack(8)
struct example1
{
short a;
long b;
};
struct example2
{
char c;
example1 struct1;
short e;
};
#pragma pack()
int main(int argc, char* argv[])
{
example2 struct2;
cout << sizeof(example1) << endl;
cout << sizeof(example2) << endl;
cout << (unsigned int)(&struct2.struct1) - (unsigned int)(&struct2) << endl;
return 0;
}

输出结果(ubuntu gcc编译)

8
16
4

下面我们来分析下

1,自然对齐(默认对齐方式,是指按结构体的成员中 size 最大的成员对齐)

struct example1
{
short a;//2字节
long b;//4字节
};

所以sizeiof(example1)为8,a后面得填充两个空白字节

2.指定对齐

· 使用伪指令#pragma pack (n),编译器将按照 n 个字节对齐;
· 使用伪指令#pragma pack (),取消自定义字节对齐方式。
注意:如果#pragma pack (n)中指定的 n 大于结构体中最大成员的 size,则其不起作用,结构体
仍然按照 size 最大的成员进行对界。

#pragma pack(8)
struct example1
{
char a;

int b;

short c;
};

#pragma pack()

最大字节数为4所以不起作用大小为12

若顺序变为

#pragma pack(8)
struct example1
{

int b;

char a;

short c;
};

#pragma pack()

大小为8,以4字节对齐,a后填充一个空白字节,再接着2字节大小的c,所以大小为8

现在我们就可以很清楚的知道开始拿到题的答案由来了;

example1中最大字节为4指定对齐失效所以按4字节对齐大小为8;

example2中最大字节为example1中的long b所以也是按4字节对齐大小为16

由于example2按4字节对齐所以(unsigned int)(&struct2.struct1) - (unsigned int)(&struct2)

等于char c按4字节对齐的大小为4

 再举个例子,看看在默认对齐规则下,各结构体成员的对齐规则:

typedef struct A 

    char c;  //1个字节

    int d;  //4个字节,要与4字节对齐,所以分配至第4个字节处

    short e;  //2个字节, 上述两个成员过后,本身就是与2对齐的,所以之前无填充

 }; //整个结构体,最长的成员为4个字节,需要总长度与4字节对齐,所以, sizeof(A)==12 

typedef struct B 

    char c;  //1个字节

    __int64 d;  //8个字节,位置要与8字节对齐,所以分配到第8个字节处

    int e;  //4个字节,成员d结束于15字节,紧跟的16字节对齐于4字节,所以分配到16-19

    short f;  //2个字节,成员e结束于19字节,紧跟的20字节对齐于2字节,所以分配到20-21

    A g;  //结构体长为12字节,最长成员为4字节,需按4字节对齐,所以前面跳过2个字节

//24-35字节处

    char h;   //1个字节,分配到36字节处

    int i;   //4个字节,要对齐4字节,跳过3字节,分配到40-43 字节

}; //整个结构体的最大分配成员为8字节,所以结构体后面加5字节填充,被到48字节。故:

//sizeof(B)==48;

总结:1,默认对齐,按按结构体的成员中 size 最大的成员对齐

            2,伪指令#pragma pack (n),编译器将按照 n 个字节对齐

            3,有效对齐大小=min(指定对齐n,max(结构体的成员中 size),系统默认对齐值(linux 4,windows 8));

            4,大小和变量类型和声明顺序有关

抱歉!评论已关闭.