C语言中联合体操作触发总线错误的原因是什么?
总线错误的底层原因:内存对齐违规
核心触发逻辑
你遇到的异常和char能不能存17完全无关,问题本质是非对齐地址的int类型内存访问触发了CPU的对齐检查异常:
- 联合体的对齐规则是取所有成员中最大的对齐要求,常规系统中
int要求4字节自然对齐,因此联合体u的起始地址一定是4的整数倍。 u.a[1]的地址 = 联合体起始地址 + 1,也就是4n + 1,这个地址不符合int类型的对齐要求(int类型的访问地址必须是自身长度4的整数倍)。- 你把这个地址强制转换为
int*后解引用赋值,本质是要求CPU向一个非4字节对齐的地址写入4字节的int值,而非写入单个char值。
硬件层面的异常原因
绝大多数RISC架构(ARM、MIPS、SPARC等)的CPU设计时就不支持非对齐的基本类型内存访问:
- 内存控制器和CPU总线的读写是按对齐块设计的,一次读写固定长度的对齐内存块(比如4字节),如果访问地址不对齐,需要额外拆分两次读写再拼接数据,很多嵌入式/低功耗架构没有集成这个额外的处理逻辑。
- 当CPU检测到访问地址不符合对应数据类型的对齐要求时,会直接抛出对齐错误(Alignment Fault),也就是你看到的总线错误。
补充:x86/x86_64架构为了兼容性,支持非对齐内存访问,只是会损失性能不会触发总线错误,但这种写法属于C语言标准明确的未定义行为,跨平台运行必然出现异常。
内容的提问来源于stack exchange,提问作者ADBeveridge
相关产品推荐
相关产品推荐

