【字节对齐】
<note>
1. ## 自身实践经验总结 ##
1. ### 例子
/*C在线编译,C语言web在线运行平台(不支持输出中文)*/
// http://yishouce.com/c/run
#include <stdio.h>
#include <string.h>
#pragma pack (1) // 注. 如果这里改成 2 或 4,结果就不一样了。
struct aa {
int a;
} ;
#pragma pack ()
#pragma pack (8)
struct bb{
char a; // [0, 1]
struct aa b; // [1, 5] 把 b 当成一个变量,大小 4,自身对齐 1
};
#pragma pack ()
void main(void)
{
printf("%d\n",sizeof(struct aa)); // 输出 4
printf("%d\n",sizeof(struct bb)); // 输出 5
printf("------------------\n");
}
2. ### 例子 2 union 字节对齐
/*C在线编译,C语言web在线运行平台(不支持输出中文)*/
// http://yishouce.com/c/run
#include <stdio.h>
#include <string.h>
#define OFFSET(st, field) (size_t)&(((st*) 0)->field)
// 选最大的 4 * 5 = 20, 但自身对齐 8 字节, 所以 ---> [0 - 24]
typedef union { double i; int k[5]; char c;} DATE;
// DATE 当成一个变量,自身对齐 8 字节
typedef struct data4 { char cat; DATE dag;} data4;
void main(void)
{
printf("%d\n",sizeof(DATE)); // 输出 24
printf("%d\n",OFFSET(data4, dag)); // 输出 8
printf("%d\n",sizeof(struct data4)); // 输出 32, 即: [0 ~ 8] [8 ~ 32]
}
2. ## 学习记录 记忆索引点 ##
1. ### 对齐参数
# http://www.cnblogs.com/dolphin0520/archive/2011/09/17/2179466.html
除了变量的 <自身对齐参数> 外,还有一个对齐参数,
就是每个<编译器默认的对齐参数> #pragma pack(n),这个值可以通过代码去设定,
如果没有设定,则取系统的默认值。
在windows(32) / VC6.0下,n 的取值可以为 1、2、4、8,默认情况下为 8。
在linux(32)/GCC下,n的取值只能为1、2、4,默认情况下为4。
2. ### <自身对齐原则>和<整体对齐原则>
※ 每个 <变量> 相对于结构体的 <首地址的偏移量> 必须是<对齐参数的整数倍>,
这句话中的对齐参数是取: min(自身对齐参数, #pragma pack(n)) 。
举例:
比如在结构体 A 中有变量int a,a的自身对齐参数为4(环境为windows/vc),
而 VC 默认的对齐参数为 8,取较小者,则对于a,
它相对于结构体 A 的起始地址的偏移量必须是 4 的倍数。
※ <结构体整体变量> 所占空间的大小是<对齐参数>的整数倍。
这句话中的对齐参数有点复杂它是取结构体中: min (所有变量的对齐参数的最大值,
系统默认对齐参数 #pragma pack(n))。
举个例子:
① #pragma pack(2) struct {int a, short b} , 整体便是 min (max(a,b) , 2) = 2;
② #pragma pack(8) struct {int a, short b} , 整体便是 min (max(a,b) , 8) = 4;
3. ### 结构体的继承关系 # http://www.cnblogs.com/webary/p/4721017.html
※ 基类的成员总是在派生类的前面。而且即使有字节对齐,
基类对齐后派生类的成员不会占用基类填充的字节,即计算好基类所占字节数后,这些字节只能由基类拥有,
不能被派生类的成员占用。
举例:
struct A {
int a;
char b;
};
struct B:A { // 注意是 A 整体对齐后,才开始 B 的成员。
char c;
int d;
long long e;
};
/*
0 4 8 12 16 24
| | | | | |
aaaab---c---ddddeeeeeeee
*/
4. ###
3. xxxx ...
// 参考资料
http://www.cnblogs.com/dolphin0520/archive/2011/09/17/2179466.html
// 结构体字节对齐 [note: 表格不错,不同平台上 double 值自身对齐方式不一样]
http://www.cnblogs.com/mashang/archive/2011/03/24/1993512.html
// 字节对齐详解 [note: 例子挺不错的]
http://www.cnblogs.com/webary/p/4721017.html
// struct / class等内存字节对齐问题详解 [note: 继承的例子不错]
http://www.cnblogs.com/clover-toeic/p/3853132.html
/* C语言字节对齐问题详解 [note: OFFSET宏定义可取得指定结构体某 <成员>
在结构体内部的<偏移>: #define OFFSET(st, field) (size_t)&(((st*) 0)->field) ]
*/
http://blog.chinaunix.net/uid-20672257-id-3138843.html
/* struct的成员对齐问题-结构体实际大小问题
[note : 例子输出和文中不一致,可以尝试在在线运行平台自己试试]
*/
struct 结构体 、 union 枚举 及 #pragma pack 字节对齐
最新推荐文章于 2023-09-04 13:53:06 发布