目前位置: VCer资源中心 >>> VCer文章 >>> C++/MFC基础

[本帖已阅读2247次 分值80 回复0次] 张贴资源 发回信箱 控制面板

sizeof 和 alignment(对齐)

提供者:jerry 张贴时间:2004-03-08 20:18:44.0 出处:bbs白云黄鹤站 作者:不祥

sizeof 和 alignment(对齐)(2004-03-08 20:18:44.0)


大头


 
级别: VCer师长
头衔: VCer创始人

经验: 22768
作品: 121
分会: 华中分会
注册: 2003-12-04 10:47:17.0
登录: 2007-06-23 10:17:58.0

sizeof 和 alignment(对齐)

xueweizhong(原作)

sizeof 和 alignment(对齐)

1: alignment的定义

alignment指的是对象的开始地址必须满足条件: 

>>#pragma pack(push, 1) 

<<任何地址  

>>#pragma pack(push, 2)

<<偶数地址 

>>#pragma pack(push, 4)

<<地址必须是4的倍数

>>#pragma pack(push, 8)

<<地址必须是8的倍数

2: 基本类型T的alignment(T)

对齐值就是上面所说的1, 2, 4, 8

现在对应于每个类型T, 都有一个alignment(T)和T对应,

这个对应关系究竟如何呢:

(以下针对我们现在所碰到的编译器而言)

<< char -->  1 (永远是1)

<< short

#pragma pack(1) --> 1

#pragma pack(2) --> 2

#pragma pack(4) --> 2 // 呵呵,这里是关键

...                      --> 2

<< int

#pragma pack(1) --> 1

#pragma pack(2) --> 2

#pragma pack(4) --> 4 // 呵呵,这里是关键

...                      --> 4

...

这里就有了一个概念, 我们尚且将其命名为

internal_PACK(T):

internal_PACK(char) = 1

internal_PACK(short) = 2

internal_PACK(int) =4

internal_PACK(int64) = 8

...

和当前编译器的对齐方式无关。

编译其当前设置的#pragma pack(n)值我们命名为

PACK (= n)

那我们就有公式:

if (internal_PACK(T) < PACK)

alignment(T, PACK) = internal_PACK(T)

else

alignment(T, PACK) = PACK

下面的这个对任何类型T都成立:

alignment(T) <= PACK                          ----------------------------

----#1

3  struct(or class)类型ST的alignment(ST)

alignment(ST) = max { alignment(T) | T 是ST的data member 的类型 }

4  举例

<<

#pragma pack(1)

struct A

{

....

};

由#1, 在pack(1)的情况下所有的 alignment(type)≡1

<<

#pragma pack(4)

struct A

{

char ch;

short sh;

};

alignment(ch) = 1

alignment(sh) = 2

alignment(A)  = 2

<<

#pragma pack(8)

struct A

{

char ch;

int n;

char ch;

};

alignment(n) = 4

alignment(A) = 4

<<

#pragma pack(2)

struct A

{

char ch;

int n;

char ch;

};

alignment(n) = 2

alignment(A) = 2

5:  sizeof(T)

<<

对基本类型来说 

sizeof(T)   = internal_PACK(T)

<<

对结构类型ST来说

把最后一个数据成员m_last去掉后形成的结构叫ST~

sizeof(ST) = sizeof(ST~) + last_size + patch

其中

<<

last_size = member_patch + sizeof(m_last)

member_patch = [sizeof(ST~) 到 比它的alignment(m_last)倍数的最小距

离] ;

<<

patch     = [sizeof(ST~) + last_size到比它大的alignment(ST)倍数的最

小距离]

其中

<<

member_patch是因为m_last要地址对齐alignment(m_last)

<<

patch 是因为如果声明一个数组的话:

ST st[2];

为了满足

1:  st[1] 地址alignment(ST)对齐

2:  sizeof(st) = sizeof(st1) + sizeof(st2)

关键是第二条

所以需要patch把余下的空间补满。

注:转载文章需注明来源:VCer.net 文章地址:http://vcer.net/1047125755318.html

  如果你觉得VCer.net不错,而且你愿意为VCer.net捐赠一元钱,那么点击后面的捐赠按钮吧:) vcer.net捐赠

[回复该贴] [加入个人书签]
[投票结果]

A: 评分 10 0% (0 票)
B: 评分 5 0% (0 票)
C: 评分 0 0% (0 票)
D: 评分 -5 0% (0 票)
E: 评分 -10 0% (0 票)