C语言——结构体的内存存储规则

一、引言

cpp 复制代码
struct stu1
{
	char a;
	short b;
	int c;
};
struct stu2
{
	char a;
	int c;
	short b;
};

int main()
{
	//输出结构体所占字节大小
	printf("%d\n", sizeof(struct stu1));  // 结果:8
	printf("%d\n", sizeof(struct stu2));  // 结果:12
}

在 C 语言中定义结构体时,成员变量顺序不同,最终结构体占用的内存大小也不同 ,并非简单把所有成员字节数相加。这背后就是结构体内存对齐机制。

二、内存对齐核心思想

(一)为什么要内存对齐

计算机CPU访问内存数据时,不会零散逐字节读取,而是优先以2的整数倍字节批量访问,常见为2Byte、4Byte、8Byte,以此提升读写效率。

内存对齐是为了让每一个成员的内存尽可能保持对齐,这样CPU一次访问的字节数,就可以直接完整取到这个元素。

核心思想:用空间换取访问时间效率

(二)内存对齐规则

1.第一个成员在与结构体变量偏移量为0的地址处

2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处

(1)对齐数 = 编译器默认对齐数与该成员大小的较小值

(2)VS环境下默认对齐数是8

3.结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍

4.如果是嵌套结构体

(1)嵌套的结构体对齐到自己的最大对齐数的整数倍处

(2)结构体整体大小就是"所有最大对齐数(含嵌套的对齐数)"的整数倍

cpp 复制代码
struct stu1
{
	char a;		// 偏移 0,占用 1 字节 -> 【0】
    			// 偏移 1,"浪费 1 字节"(为了对齐)
	short b;	// 对齐数:min(2, 8) = 2
    			// 从偏移 2 开始,占用 2 字节 -> 【2, 3】
	int c;		// 对齐数:min(4, 8) = 4
    			// 从偏移 4 开始,占用 4 字节 -> 【4, 5, 6, 7】
};	

// 总大小:8 Byte
// 校验:8 % 最大对齐数(4) == 0,满足规则!
cpp 复制代码
struct stu2
{
	char a; 	// 偏移 0,占用1字节   【0】
         		// 偏移 1、2、3,浪费3字节(对齐填充)
	int c;		// 对齐数:min(4, 8) = 4
         		// 偏移 4 开始,占用4字节 【4,5,6,7】
	short b;	// 对齐数:min(2, 8) = 2
         		// 偏移 8 开始,占用2字节 【8,9】
};	

// 当前总长度:10 Byte
// 校验:10 % 最大对齐数(4) != 0,不满足规则!
// 自动填充字节,补齐到 12 Byte

(三)手动修改默认对齐数

cpp 复制代码
#pragma pack(n)    // 设置默认对齐数为 n(n 只能是 1、2、4、8、16)
#pragma pack()     // 取消手动设置,恢复编译器默认(VS 默认 8)
相关推荐
在世修行14 分钟前
从零打造 C# 工业视觉检测系统(八):Modbus RTU 协议解析与 PLC 剔除控制实战
开发语言·c#
sunburn-41 分钟前
Java 队列全面详解:从入门到面试实战
java·开发语言·汇编·ide·idea
AI直播技术杂谈44 分钟前
AI直播推流链路中延迟优化的通用技术方案
开发语言·人工智能·php
Dxy12393102162 小时前
python 中的 APScheduler 使用详解
开发语言·python
捷瑞电子工坊2 小时前
C语言二维数组在内存中是如何存储的?
c语言·二维数组·内存存储·数组底层
lilili也3 小时前
visual studio add matlab
c语言·c++
福如意如我心意3 小时前
java虚拟线程和Go协程的区别
开发语言
weixin_440784113 小时前
Java基础常见题
java·开发语言·python·java基础
(Charon)3 小时前
【C++】多线程死锁:产生原因、复现与解决方法
开发语言·c++·算法
跨境小彭3 小时前
Python列表去重的6种高效方法(含保留顺序+性能对比)
开发语言·python