sizeof 和 alignment(对齐)

本文详细解释了C/C++中对象的对齐规则及其对sizeof运算符的影响。通过对不同编译器设置的理解,展示了基本类型及结构体类型的对齐方式,并通过实例说明了对齐在内存布局中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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把余下的空间补满。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值