结构体内存对齐总结

  首先我们都知道结构体是多个变量的集合,在其中可以存放整型,浮点型等等各种,然后结构体内存是如何对齐的呢,他并不是按连续顺序去排下去的,首先我们先上一段代码

#include<iostream>
#include<cstdlib>
using namespace std;

struct a{
	int m;
	char n;
	double c;

};

struct b{
	char o;
	double p;
	int j;
};

int main()
{
	cout << sizeof(a) << endl;
	cout << sizeof(b) << endl;
	system("pause");
}

这段代码运行出来的结果得出a的内存大小为16,b的内存大小为24,同样的三个类型,只是排列顺序不同,结构体的大小就不一样。下面是对齐规则

结构体内存对齐规则
1. 第一个成员在与结构体偏移量为0的地址处。
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数 = 编译器默认的一个对齐数 与 该成员大小相比中的较小值。
VS中默认的对齐数为8,gcc中的对齐数为4
3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是
所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

那么为什么要内存对齐呢

内存对齐大大提高了cpu的读取速率。

1.还有并非所有硬件平台都可以访问任何地址上的任何数据,有些硬件平台也只能访问某些特定地址处某些特定类型的数据。

2.内存对齐的CPU只需要读取一次,没有内存对齐,CPU则需要读取两次。

如何让结构体按照指定的对齐参数进行对齐

设置对齐参数可在结构体struct之前加上#pragma pack(对齐数),在struct之后加上#pragma pack;便可以设置对齐参数

 如何知道结构体中某个成员相对于结构体起始位置的偏移量

我们可以使用这个#define offsetof(s,a)  (size_t)  (((s*)0)->a),这个用法就是我们告诉编译器有一个指针指向结构体s,而它的值是0,然后我们取结构体中的a,a的地址就是a的偏移量了。

#include<iostream>
#include<cstdlib>
using namespace std;
#define offsetof(s,a) (size_t) &(((s*)0)->a)

struct a{
	int m;
	char n;
	double c;

};
#pragma pack(4)
struct b{
	char o;
	double p;
	int j;
};
#pragma pack;
int main()
{
	cout <<"a的内存大小为"<< sizeof(a) << endl;
	cout <<"b的内存大小为"<< sizeof(b) << endl;
	cout << offsetof(b, p) << endl;
	system("pause");
}

猜你喜欢

转载自blog.csdn.net/hgxy123/article/details/84316723