概述
上一篇:【内存对齐】第三篇·显式干预对齐的三种方法
除了 struct,其他构造类型包括 union,array。我们通过前面的讨论,已经基本理清了简单结构体的内存对齐规则。 下面将探讨 “union 联合体”,“array 数组” 的对齐规则。
- Array 数组的对齐规则
- Union联合体/共用体 的对齐规则
Array 数组的对齐规则
先来讨论下 array 数组类型 的对齐规则。数组本身就是由很多相同类型的数据类型组成的,所以有:
a. 其元素的宽度应该是 2 的倍数(不算最小的char[1]);
b. 只要保证一个元素是对齐的,其他元素都会自动对齐。
给出一个示例程序:
#include "stdio.h"
char ph;
//Add a char placeholder to make struct start from an odd pointer value.
char test[1];
int main(void)
{
printf("Size: Char[%d], Short[%d], int[%d], long[%d], longlong[%d]rn", sizeof(char), sizeof(short), sizeof(int), sizeof(long), sizeof(long long));
printf("Size of Test = %drn", sizeof(test));
printf("Address of Test = %prn", test);
return 0;
}
不断修改数组 test[1] 的定义,我们来找规律:
char test[1] Size: 1 Address: 0x00000001004071a1
char test[2] Size: 2 Address: 0x00000001004071a2
char test[3] Size: 3 Address: 0x00000001004071a4
char test[4] Size: 4 Address: 0x00000001004071a4
char test[6] Size: 6 Address: 0x00000001004071a4
char test[8] Size: 8 Address: 0x00000001004071a8
char test[16] Size: 16 Address: 0x00000001004071b0
char test[32] Size: 32 Address: 0x00000001004071c0
char test[64] Size: 64 Address: 0x00000001004071c0
short test[1] Size: 2 Address: 0x00000001004071a2
short test[2] Size: 4 Address: 0x00000001004071a4
short test[3] Size: 6 Address: 0x00000001004071a4
short test[4] Size: 8 Address: 0x00000001004071a8
short test[6] Size: 12 Address: 0x00000001004071a8
short test[8] Size: 16 Address: 0x00000001004071b0
short test[16] Size: 32 Address: 0x00000001004071c0
short test[32] Size: 64 Address: 0x00000001004071c0
short test[64] Size: 128 Address: 0x00000001004071c0
int test[1] Size: 4 Address: 0x00000001004071a4
int test[2] Size: 8 Address: 0x00000001004071a8
int test[3] Size: 12 Address: 0x00000001004071a8
int test[4] Size: 16 Address: 0x00000001004071b0
int test[8] Size: 32 Address: 0x00000001004071c0
int test[16] Size: 64 Address: 0x00000001004071c0
int test[32] Size: 128 Address: 0x00000001004071c0
根据以上可以总结其规律,和结构体还蛮像的:
- Adress 猜想:数组首地址只和数组整体大小size有关。
- 当数组大小小于0x04时,起始地址是大于等于2^(log2(size)的最小整数)的整数倍。
- 当数组大小大于0x04,小于0x10时,起始地址是小于等于2^(log2(size)的最大整数)的整数倍。
- 当数组大小大于0x10时,小于0x20时,起始地址是(0x10*(size/16))的整数倍。
- 当数组大小大于0x20时,起始地址是0x20的整数倍。
- Size猜想:数组的大小等于“元素的大小*元素的个数”。
Union联合体/共用体 的对齐规则
接下来探究一下union 联合体(共用体)的对齐规则。给出例程:
#include "stdio.h"
char ph;
//Add a char placeholder to make struct start from an odd pointer value.
union test_u{
char grass;
} test;
int main(void)
{
printf("Size: Char[%d], Short[%d], int[%d], long[%d], longlong[%d]rn", sizeof(char), sizeof(short), sizeof(int), sizeof(long), sizeof(long long));
printf("Size of Test = %drn", sizeof(test));
printf("Address of Test = %prn", &test);
return 0;
}
不断修改 union 定义,得到:
char Size: 1 Address: 0x00000001004071a1
char/char Size: 1 Address: 0x00000001004071a1
char/char/short Size: 2 Address: 0x00000001004071a2
char/short/int Size: 4 Address: 0x00000001004071a4
char/short/int/int Size: 4 Address: 0x00000001004071a4
根据联合体的特点,联合体中的各个成员占用同一块存储空间,可以得到:
a. 其起始地址是成员中最宽的类型的宽度的整数倍。
b. 其大小是成员中最大的类型的大小。
连载中… by 2021/06/22
下一篇:【内存对齐】第五篇·嵌套构造类型的对齐规则{结构体}
最后
以上就是老实楼房为你收集整理的【内存对齐】第四篇·Array、Union内存对齐的规律与原则Array 数组的对齐规则Union联合体/共用体 的对齐规则的全部内容,希望文章能够帮你解决【内存对齐】第四篇·Array、Union内存对齐的规律与原则Array 数组的对齐规则Union联合体/共用体 的对齐规则所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复