结构体内存对齐

首先来看一段代码

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include<Windows.h>

 struct Node
{
	int date;
	char next;
};
int main()
{
	struct Node n;
	printf("%d", sizeof(n));
	system("pause");
	return 0;
}

输出结果为8
以我们平时的了解,结构体占用内存字节应该是该结构体成员占用内存字节的和,在这段代码中输出结果应该是5。但是为什么会输出8呢?
这就牵扯到一个知识点 结构体内存对齐
想要看清楚刚才为什么会出现8,我们来用一个宏“offsetof”
这个宏实现的是一个结构成员相对于结构开头的字节偏移量
下面是 offsetof() 宏的声明。
offsetof(type, member-designator)
C 标准库 - <stddef.h>
用这个库宏可以实现对结构体字节偏移量的观察。

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include<Windows.h>
#include<stddef.h>

struct Node
{
	int date;
	char next;
};
int main()
{
	struct Node n;
	printf("%d\n", sizeof(n));
	printf("%d\n", offsetof(struct Node, date));
	printf("%d\n", offsetof(struct Node, next));
	system("pause");
	return 0;
}

结果是 8
0
4
可以看到Int类型的成员并没有偏移,但是char类型的成员偏移量为4,所以造成了这个结构体的长度为8
结构体为什么要内存对齐呢?
1:一些硬件规定数据必须在特定位置开始取;
2:处理器在访问未对齐的内存需要进行2次访问,而对齐的内存只需要进行一次访问就行。

        结构体内存对齐的规则是什么?
        1:结构体的第一个成员都要放在起始位置的0偏移处;
        2:从第二个成员开始,每个成员都要放在某个对齐数的整数倍的偏移处;
        这个对齐数:成员自身大小和默认对齐数的较小值
        默认对齐数:
        VS:8
        linuix : 4.
		3:结构体的总大小必须是所有成员的对齐数中最大对齐数的整数倍。
		我们继续看一个结构体嵌套类型的计算
#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include<Windows.h>
#include<stddef.h>

struct Diss
{
	double num;//  0偏移量  0--7
	char name;// 8偏移量    8
	int age;// 4偏移量      12--15
}d;// 8+4+4 最后结果取最大对齐数的整数倍所以是16
struct Node
{
	int date;//0偏移量 0--3
	char next;//4偏移量 4
	struct Diss n;//由于5不是24的倍数,结构体会偏移到8开始    8----24
}p;//4+4+16   这里最大对齐数为8而不是16,因为默认对齐数和自身长度比较选的是较小值,所以在此事的最大对齐数是8
int main()
{
	struct Node n;
	printf("%d\n", sizeof(d));
	printf("%d\n", offsetof(struct Node,date));
	printf("%d\n", offsetof(struct Node, next));
	printf("%d\n", offsetof(struct Node, n));
	printf("%d\n", sizeof(p));
	system("pause");
	return 0;
}

16
0
4
8
24
结果是不是如你所愿呢?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值