1

このコードでバス エラーが発生する理由を理解したいと思います。

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

2 に答える 2

11

アライメントの問題であることは間違いありません。多くのアーキテクチャでは、特定の型を適切に配置する必要があります。たとえば、4 バイト整数は4 バイト境界で開始する必要があります。

アライメントされていないデータにアクセスすると、気にしないアーキテクチャもあれば、実行速度が遅くなるアーキテクチャもあれば、(この場合のように) 悲鳴を上げるヒープに陥るアーキテクチャもあります。

integerを作成pすると、スタック上の正しい倍数のアドレスに正しく配置されます。

そのアドレスをバイト上に移動し、それを として逆参照するとintSIGBUS.

Oracle のこのリンクは、配置要件を示しています。要するに:

  • short 整数は 16 ビット境界で整列されます。
  • int 整数は 32 ビット境界で整列されます。
  • long 整数は、SPARC システムの 64 ビット境界に整列されます。
  • long long 整数は 64 ビット境界で整列されます。
于 2009-12-12T06:35:07.173 に答える
1

16 ビット量は 16 ビットまたは 2 バイト アラインメントで、32 ビット (4 バイト) は 4 の倍数のアドレスに格納する必要があります。

多くの CPU は非整列アクセスをサポートしていますが、チップ内の余分な回路と、余分なメモリ バス サイクルを実行して奇数バイトを取得するための余分な実行時間がかかります。特に一般的な RISC プロセッサの哲学では、速度の向上と回路の単純化のためにデータを慎重にレイアウトするためにコンパイラとプログラマの側でより多くの注意を払う必要があることは、許容できるトレードオフです。

ちなみに、そのような低いアドレスが有効なメモリにあるとは考えにくいです。しかし、あなたの例は、アラインメント例外が SEGFAULT 例外よりも優先されることを示しています。

于 2009-12-12T06:36:25.167 に答える