10

根据维基百科页面Segmentation fault,未对齐的内存访问可能会导致总线错误。本文给出了一个关于如何触发总线错误的示例。在示例中,我们必须启用对齐检查才能查看总线错误。如果我们禁用这种对齐检查怎么办?

该程序似乎运行正常。我有一个程序经常访问未对齐的内存,它被很多人使用,但没有人向我报告总线错误或其他奇怪的结果。如果我们禁用对齐检查,未对齐内存的副作用是什么?

平台:我正在研究x86 / x86-64。我还通过在 Mac 上使用“gcc -arch ppc”编译它来尝试我的程序,它可以正常工作。

4

3 回答 3

14
  1. 访问未对齐的内存可能要慢得多(例如慢几倍)。

  2. 并非所有平台都支持非对齐访问——例如,x86 和 x64 支持,但 ia64 (Itanium) 不支持。

  3. 编译器可以模拟未对齐的访问(例如,VC++ 对在 ia64 上声明的指针执行此操作__unaligned)——通过插入额外的检查来检测未对齐的情况,并分别加载/存储跨越对齐边界的对象部分。然而,这甚至比原生支持它的平台上的非对齐访问还要慢。

于 2009-09-30T08:54:33.680 回答
6

这在很大程度上取决于芯片架构。x86 和POWER非常宽容,Sparc、Itanium 和 VAX 抛出不同的异常。

于 2009-09-30T09:05:46.843 回答
2

考虑以下我刚刚在 ARM9 上测试过的示例:

//Addresses       0     1     2    3     4     5     6     7      8    9
U8 u8Temp[10] = {0x11,0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00};

U32 u32Var;

u32Var = *((U32*)(u16Temp+1));  // Let's read four bytes starting from 0x22

// You would expect that here u32Var will have a value of 0x55443322 (assuming we have little endian)
// But in reallity u32Var will be 0x11443322!
// This is because we are accessing address which %4 is not 0.
于 2013-03-12T23:36:49.050 回答