网站 新增线路 备案,做网站的难点是什么,福建工商网上登记平台,网站新闻页设计在 C 语言中#xff0c;构造体#xff08;struct#xff09;和共同体#xff08;union#xff09;允许我们将多种数据类型组合到一起。除了常见的基本数据类型之外#xff0c;经常还会在它们中嵌入数组和指针。由于数组的内存是连续分配的#xff0c;而指针的大小与平台… 在 C 语言中构造体struct和共同体union允许我们将多种数据类型组合到一起。除了常见的基本数据类型之外经常还会在它们中嵌入数组和指针。由于数组的内存是连续分配的而指针的大小与平台相关32 位一般为 4 字节64 位一般为 8 字节计算内存大小时就需要特别注意内存对齐和填充的影响。本文将通过具体示例说明如何计算包含数组和指针的构造体和共同体的内存大小。 一、构造体Struct中包含数组和指针
1.1基本原理
数组数组内存占用空间为“数组元素个数×单个元素大小”且所有元素是连续排列。指针指针只存储一个地址其大小固定取决编译平台与指向数据无关。内存对齐与填充编译器为了提高内存访问效率会按照每个成员的对齐要求进行排列。如果某个成员的起始地址不满足对齐要求编译器会在前面插入填充字节。同时整个结构体的大小也会被调整为结构体中最大对齐要求的整倍数。
1.2示例 构造体包含数组和指针 假设在 64 位系统下指针大小为 8 字节int 为 4 字节char 为 1 字节如下构造体的定义为例
struct Example {char a; // 1 字节int b; // 4 字节要求 4 字节对齐char arr[3]; // 数组占 3 字节int *ptr; // 指针占 8 字节64 位系统
};内存布局分析
1.成员 achar
从偏移 0 开始占 1 字节。
2.成员 bint
由于 int 要求 4 字节对齐而 a 只占 1 字节所以在 a 后面需要 3 字节填充使得 b 的起始地址为偏移 4。b 占 4 字节从偏移 4 到 7。
3.成员 arr[3]数组
紧接在 b 后面从偏移 8 开始。数组大小为 3 字节覆盖偏移 8、9、10。
4.成员 ptr指针
指针要求 8 字节对齐而当前下一个可用偏移为 11不满足 8 字节对齐因为 11 不是 8 的倍数。编译器需要在 arr 后插入 5 字节填充使得 ptr 从偏移 16 开始。ptr 占 8 字节从偏移 16 到 23。
5.整体大小调整
当前各部分占用总字节数为 24 字节023而最大对齐要求为 8 字节24 已经是 8 的倍数因此最终结构体大小为 24 字节。
1.3 嵌套构造体中包含数组和指针 假设在 64 位系统下指针大小为 8 字节int 为 4 字节char 为 1 字节如下构造体的定义为例
struct Example {char a; // 1 字节int b; // 4 字节要求 4 字节对齐char arr[3]; // 数组占 3 字节int *ptr; // 指针占 8 字节64 位系统
};内存布局分析
1.成员 achar
从偏移 0 开始占 1 字节。
2.成员 bint
由于 int 要求 4 字节对齐而 a 只占 1 字节所以在 a 后面需要 3 字节填充使得 b 的起始地址为偏移 4。b 占 4 字节从偏移 4 到 7。
3.成员 arr[3]数组
紧接在 b 后面从偏移 8 开始。数组大小为 3 字节覆盖偏移 8、9、10。
4.成员 ptr指针
指针要求 8 字节对齐而当前下一个可用偏移为 11不满足 8 字节对齐因为 11 不是 8 的倍数。编译器需要在 arr 后插入 5 字节填充使得 ptr 从偏移 16 开始。ptr 占 8 字节从偏移 16 到 23。
5.整体大小调整
当前各部分占用总字节数为 24 字节023而最大对齐要求为 8 字节24 已经是 8 的倍数因此最终结构体大小为 24 字节。
二、共同体union中包含数组和指针
2.1 基本原理 在共同体中所有成员共享同一块内存其大小由最大成员的大小决定同时也需要满足该成员的对齐要求。即使共同体中包含数组和指针原则也是一致的。
2.2 示例共同体中包含数组和指针
union Union {int arr[4]; // 数组4 个 int每个 4 字节总共 16 字节double *dptr; // 指针8 字节64 位系统char c[10]; // 数组10 个 char总 10 字节
};内存大小计算
arr[4] 占 4 × 4 16 字节dptr 占 8 字节c[10] 占 10 字节
取最大值 最大成员为 arr[4]大小为 16 字节。 同时需要考虑最大对齐要求假设 int 要求 4 字节而指针要求 8 字节由于最大成员数组的元素对齐为 4 字节但联合体的整体对齐要求通常取决于所有成员中最大的这里可能由指针决定为 8 字节不过最终分配空间依旧是 16 字节且该空间会按 8 字节对齐。因此该共同体的总大小为 16 字节。
三、总结与注意事项
1.构造体struct
内存分布为成员按照声明顺序排列。数组成员按照数组中所有元素总大小分配。指针成员只占指针本身大小不考虑所指数据。必须考虑每个成员的对齐要求必要时插入填充字节整体大小也需调整为最大对齐要求的整数倍。嵌套构造体时先计算内部结构体的大小再按照外部成员的排列顺序计算整体大小。
2.共同体union
所有成员共享同一块内存大小取决于最大的成员同时满足对齐要求。数组和指针的计算方法依然适用但只取最大值即可。