我想了解为什么我收到此代码的总线错误。
int main()
{
int p=34;
int *pp= (int *) ((char *)&p+1);
cout<<*pp<<"\n";
return 0;
}
毫无疑问,这将是一个对齐问题。在许多体系结构中,某些类型必须正确对齐,例如 4 字节整数必须从 4 字节边界开始。
如果您访问未对齐的数据,一些架构不会关心,其他架构会运行得更慢,还有一些架构(例如在这种情况下)会陷入尖叫堆。
当您创建integerp
时,它将在堆栈上正确对齐的地址是正确的倍数。
通过将该地址向上移动一个字节,并将其取消引用为int
,您将导致SIGBUS
.
Oracle 上的此链接显示对齐要求。简而言之:
16 位数量必须以 16 位或 2 字节对齐方式存储,并且 32 位(4 字节)的地址必须是 4 的倍数。
许多 CPU 支持非对齐访问,但它需要芯片中的额外电路,以及额外的执行时间来运行额外的内存总线周期来获取奇数字节。这是一种特别常见的 RISC 处理器理念,要求编译器和程序员更加小心地仔细布置数据以提高速度和简化电路,这是可以接受的折衷方案。
顺便说一句,无论如何,这样的低地址不太可能在有效内存中。但是您的示例确实说明了对齐异常优先于 SEGFAULT 异常。