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)
相关推荐
aqiu11111119 分钟前
【C++算法打怪专栏】8. 字符串转换整数 (atoi)
开发语言·c++·算法
爱吃香菜的初学者26 分钟前
十四.Linux——消息队列
linux·运维·开发语言
迅猛龙办公室41 分钟前
python实现倒序输出数字
开发语言·python
夏幻灵7 小时前
JavaScript this 面试:五种绑定规则、优先级与常见面试陷阱
开发语言·javascript·面试
程序猿编码7 小时前
榨干 RTX5090 算力!Qwen3 专用单卡推理引擎,手写C++/CUDA 算子实现 MTP 推测解码
开发语言·c++·大模型推理·qwen3·多模态推理
bkspiderx8 小时前
Qt 插件机制:动态扩展应用功能的核心框架
开发语言·qt·元数据·qt 插件·qpluginloader
程序员老陆8 小时前
深入理解 C++ thread_local:线程私有存储的正确打开方式
开发语言·c++·程序设计
沐晓时光9 小时前
C语言入门,深入理解指针(3)
c语言·开发语言
码云数智-园园9 小时前
unique_ptr 还是 shared_ptr?C++ 智能指针选型与内存泄漏实战分析
java·开发语言
禾小西10 小时前
07丨Redis 哨兵机制:主库故障后,如何恢复服务?
java·开发语言·redis