【问题标题】:C++ Bus error in SPARC arcitectureSPARC 体系结构中的 C++ 总线错误
【发布时间】:2010-12-25 22:34:54
【问题描述】:

我想了解为什么我收到此代码的总线错误。

int main()
{
int p=34;
int *pp= (int *) ((char *)&p+1);
cout<<*pp<<"\n";
return 0;
}

【问题讨论】:

  • 除了对齐问题,这是未定义的行为。你读书越界了。因此,该程序可能会以更具想象力的方式爆发。

标签: c++ bus-error


【解决方案1】:

这无疑是一个对齐问题。在许多架构中,某些类型必须正确对齐,例如 4 字节整数必须以 4 字节边界开始。

如果您访问未对齐的数据,一些架构不会在意,其他架构会运行得更慢,还有一些架构(例如在本例中)会陷入困境。

当您创建整数 p 时,它将在堆栈上正确对齐的地址是正确的倍数。

通过将该地址向上移动一个字节,并将其取消引用为int,您将导致SIGBUS

This link at Oracle 显示对齐要求。简而言之:

  • 短整数在 16 位边界上对齐。
  • int 整数在 32 位边界上对齐。
  • 对于 SPARC 系统,长整数在 64 位边界上对齐。
  • long long 整数在 64 位边界上对齐。

【讨论】:

  • 感谢这有很大帮助!我现在明白他们所说的非对齐地址是什么意思了。
  • 值得注意的是,许多架构会容忍未对齐的内存访问,并且只会导致性能损失(x86 和 ARM 就是这种情况),但如果内存未对齐,SPARC 尤其会导致陷阱发生尝试访问
【解决方案2】:

16 位数量必须以 16 位或 2 字节对齐方式存储,并且 32 位(4 字节)的地址必须是 4 的倍数。

许多 CPU 支持非对齐访问,但它需要芯片中的额外电路,以及额外的执行时间来运行额外的内存总线周期来获取奇数字节。这是一种特别常见的 RISC 处理器理念,即要求编译器和程序员更加小心谨慎地布置数据以提高速度和简化电路,这是可以接受的权衡。

顺便说一句,像这样的低地址不太可能在有效内存中。但是您的示例确实说明了对齐异常优先于 SEGFAULT 异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-02
    • 1970-01-01
    • 1970-01-01
    • 2021-04-17
    • 1970-01-01
    • 2017-07-01
    • 1970-01-01
    相关资源
    最近更新 更多