C++ SPARC 架构中的总线错误
我想了解为什么我在使用此代码时遇到总线错误。
int main()
{
int p=34;
int *pp= (int *) ((char *)&p+1);
cout<<*pp<<"\n";
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
毫无疑问,这将是一个对齐问题。在许多架构上,某些类型必须正确对齐,例如 4 字节整数必须从 4 字节边界开始。
如果您访问未对齐的数据,某些体系结构不会关心,其他体系结构会运行得更慢,还有其他体系结构(例如在本例中)将陷入尖叫堆。
当您创建整数
p
时,它将在堆栈上的正确倍数地址处正确对齐。通过将该地址向上移动到字节,并将其作为
int
取消引用,就会导致SIGBUS
。显示了对齐要求。简而言之:
It will no doubt be an alignment issue. On many architectures, certain types have to be aligned properly, an example being that 4-byte integers must start on a 4-byte boundary.
If you access non-aligned data, some architectures won't care, others will run slower, still others (such as in this case) will fall in a screaming heap.
When you create the integer
p
, it will be aligned correctly on the stack at an address which is a correct multiple.By moving that address up on byte, and de-referencing that as an
int
, you're causing theSIGBUS
.This link at Oracle shows the alignment requirements. In short:
16 位数量必须以 16 位或 2 字节对齐方式存储,32 位(4 字节)数量必须以 4 的倍数地址存储。
许多 CPU 支持未对齐访问,但会增加芯片中的额外电路,并且额外的执行时间来运行额外的内存总线周期来获取奇数字节。这是一种特别常见的 RISC 处理器理念,要求编译器和程序员更加小心地仔细布局数据以提高速度和简化电路,这是可以接受的权衡。
顺便说一句,无论如何,像这样的低地址不太可能位于有效内存中。但您的示例确实说明了对齐异常优先于 SEGFAULT 异常。
16-bit quantities must be stored at 16-bit or 2-byte alignment, and 32-bit (4 bytes) at addresses which are a multiple of 4.
Many CPUs support unaligned access, but it costs extra circuitry in the chip, and extra execution time to run the extra memory bus cycles to pick up the odd bytes. It is a particularly common RISC processor philosophy that requiring more care on the part of compilers and programmers to lay out data carefully for increased speed and simpler circuitry is an acceptable trade off.
By the way, it's unlikely that a low address like that would be in valid memory anyway. But your example does illustrate that the alignment exception takes priority over the SEGFAULT exception.