首页
社区
课程
招聘
[旧帖] [原创](15PB) C语言结构体大小及对齐问题 0.00雪花
发表于: 2016-1-4 11:31 1420

[旧帖] [原创](15PB) C语言结构体大小及对齐问题 0.00雪花

2016-1-4 11:31
1420
0.问题的提出
写出一个struct,然后sizeof,会发现sizeof的结果往往比声明的变量总长度大,这是因为内存对齐问题而造成的。

1.对齐的意义
许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的起始地址的值是某个数k的倍数,这就是所谓的内存对齐,而这个k则被称为该数据类型的对齐模数。这种强制的要求一来简化了处理器与内存之间传输系统的设计,二来可以提升读取数据的速度

2.对齐的原则
对齐采用的总体原则是这样的:4字节变量的存放要对齐到可以被4整除的地址上,8字节变量的存放要对齐到可以被8整除的地址上。
原则A:struct或者union的成员,第一个成员在偏移0的位置,之后的每个成员的起始位置必须是当前成员大小的整数倍;
原则B:如果结构体A含有结构体成员B,那么B的起始位置必须是B中最大元素大小整数倍地址;
原则C:结构体的总大小,必须是内部最大成员的整数倍;

3. 举例说明
struct _TEST1
{
char   c;
int    i;
double  d;
} g_stcTest;              
struct _TEST2
{
char   c;
double  d;
int    i;

} g_stcTest2;

struct _TEST3
{
double  d;
char   c;
int    i;

} g_stcTest3;

对3个结构体sizeof的结果分别为16 24 16

对TEST1而言,其内存空间分配如下:(原则2)
0  1  2  3  4  5  6  7  8   9  10  11  12  13  14  15
c1         i1  i2 i3 i4 d1 d2  d3  d4  d5  d6  d7  d8

c为char类型,占1个字节,从偏移为0的地址开始;i为int 类型,占4个字节,其起始位置应为4的整数倍,即从偏移为4的位置开始连续占4个字节;d为double类型,占8个字节,其其实位置应为8的整数倍,即从偏移为8的位置开始连续占用8个字节。最后对整个结构体占用字节数进行检查,发现一共占用16字节数,为结构体内最长类型double的整数倍;因此TEST1结构占用字节数为16。

对TEST2而言,其内存空间分配如下:(原则3)
0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
c1                    d1 d2 d3 d4 d5 d6 d7 d8 i1 i2 i3 i4

c为char类型,占1个字节,从偏移为0的地址开始;d为double类型,占8个字节,其起始位置应为8的整数倍,即从偏移为8的位置开始连续占用8个字节。i为int 类型,占4个字节,其起始位置应为4的整数倍,即从偏移为16的位置开始连续占4个字节;最后对整个结构体占用字节数进行检查,发现一共占用20字节数,不是结构体内最长类型double的整数倍,需补齐,补四位为24,此时为double的整数倍;因此TEST1结构占用字节数为24。
TEST3同TEST1不再赘述。

4.空间
在设计结构体时,一般会将占用空间小的类型排在前面,占用空间大的类型排在后面,这样可以节约一些对齐空间。

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//