关于内存对齐和对齐数的理解,虽然自己能算出某个结构体或者类对象的对齐数大小,但是一直没有去验证过自己所知的是否真的正确,直到有一天碰到了这个问题如何知道结构体中某个成员相对于结构体起始位置的偏移量?,我才意识到有必要验证一下之前自己所理解的内存对齐是否正确了.
- 于是我查找了一些博客,下面这个博客写的比较详细.
- 基于上述博客的内容,我也进行了实验
实验开始
- Linux环境下我进行了如下测试
#include<iostream>
#include<cstddef>
class Test{
public:
private:
char a;
char b;
double c;
};
class A{
public:
char a;
int t;
char c;
char b;
double e;
};
int main(){
Test t;
A a;
std::cout<<sizeof(t)<<std::endl;
std::cout<<sizeof(a)<<std::endl;
return 0;
}
-
我计算的输出结果分别为16与24
-
程序运行结果如下图
-
由上图我们可知我的计算是正确的
-
对于class A而言,我的猜想如下
- 由上图可知
- a:第一个变量地址与类的起始地址偏移量为0
- t:由于内存对齐规则,其偏移量为4
- c:其偏移量为1,由于内存对齐规则可知其与类的起始地址偏移量为8
- b:其偏移量为1,由于内存对齐规则可知其与类的起始地址偏移量为9
- c:其偏移量为8,由于内存对齐规则可知其与类的起始地址偏移量为16
那么问题来了,我该怎么验证我的猜想呢?
- 采用如下方式进行猜想的验证
#include<iostream>
#include<cstddef>
class Test{
public:
private:
char a;
char b;
double c;
};
class A{
public:
char a;
int t;
char c;
char b;
double e;
};
int main(){
Test t;
A a;
std::cout<<sizeof(t)<<std::endl;
std::cout<<sizeof(a)<<std::endl;
printf ("offsetof(class A,a) is %d\n",(int)offsetof(class A,a));
printf ("offsetof(class A,t) is %d\n",(int)offsetof(class A,t));
printf ("offsetof(class A,c) is %d\n",(int)offsetof(class A,c));
printf ("offsetof(class A,b) is %d\n",(int)offsetof(class A,b));
printf ("offsetof(class A,e) is %d\n",(int)offsetof(class A,e));
return 0;
}
- 运行结果如下
- 由此发现我的猜想是正确的.
采用offsetof可以知道类中|结构体中某个成员相对于结构体|类的其实位置的偏移量
- 库中提供的宏定义为
#define OFFSETOF(type, member) ((int64_t)&((type*)0)->member)//64位主机
#define OFFSETOF(type, member) ((int32_t)&((type*)0)->member)//32位主机