windows环境中,默认是4字节对齐。在VS2008环境中也可以进行设置对齐方式,同时下面的这句代码也可以进行设置
预处理可以设置字节对齐方式 #pragma pack(1) 代表1字节对齐
下面的处理方式以 1 字节对齐
注意:如果结构体成员变量全部定义为 unsigned char型,也不用考虑字节对齐的问题。单字节的数据本来就是连续存放的
一般来讲,关于成员变量的偏移,指的是相对于结构体起始地址,结构体变量的地址就等于第一个变量的地址
C语言里面有一个库函数专门来处理这种偏移的,在<stddef.h>头文件中,实质上offsetof是一个宏
#define offsetof(s,m) (size_t)&reinterpret_cast<const volatile char&>((((s *)0)->m))
s代表结构体类型,m代表结构体里面的成员数据,
size_t offsetof(type, member);
引申下来源
struct test
{
unsigned char x;
unsigned char y[2];
unsigned char z[6];
};
偏移大小 = 结构体成员变量地址-结构体起始地址
test t;
unsigned long offset = (unsigned long)&t.z - (unsigned long)&t;
假设咱们不想定义变量t,那怎么办呢,继续往下引申,引入一个几何问题,
假设在座标轴上由A点移动到B点,如何计算B相对于A的偏移?很显然就是 B-A。如果A为0的话,那就是B了呗
假设t的内存地址为0即(&t==0)的时候,上面的代码可简化为:
(unsigned long)&t.z
我们就可以使用另外一种方式来表达了,如下:
这是在内存上用几何的概念相对的移动,都可以表示偏移量
((test *)0)->z
最后可以改造为
#define OFFSET_OF(struct_name, struct_member) (unsigned long)(&(((struct_name *)0)->struct_member))