【问题标题】:How to demonstrate a memory misalignment error in C on a macbook pro (Intel 64 bit processor)如何在 macbook pro(英特尔 64 位处理器)上演示 C 中的内存未对齐错误
【发布时间】:2017-01-04 21:02:33
【问题描述】:

为了理解 C 内存对齐或任何术语(数据结构对齐?),我正在尝试编写导致对齐错误的代码。让我了解这一点的最初原因是我正在编写数据解析代码,该代码读取通过网络接收的二进制数据。数据包含一些 uint32s、uint64s、浮点数和双精度数,我想确保它们不会因为我的解析代码中的错误而损坏。

由于未对齐而导致某些问题的尝试失败:

uint32_t integer = 1027;
uint8_t * pointer = (uint8_t *)&integer;
uint8_t * bytes = malloc(5);
bytes[0] = 23; // extra byte to misalign uint32_t data
bytes[1] = pointer[0];
bytes[2] = pointer[1];
bytes[3] = pointer[2];
bytes[4] = pointer[3];
uint32_t integer2 = *(uint32_t *)(bytes + 1);
printf("integer: %u\ninteger2: %u\n", integer, integer2);

在我的机器上,两个整数打印出来的结果是一样的。 (带有 Intel 64 位处理器的 macbook pro,不确定究竟是什么决定了对齐行为,是架构吗?还是确切的 CPU 型号?或者编译器可能?我使用 Xcode 如此叮当)

我猜我的处理器/机器/设置支持未对齐读取,因此它采用上述代码没有任何问题。

如果由于代码未考虑对齐而导致解析 uint32_t 失败的情况是什么?有没有办法让它在现代英特尔 64 位系统上失败?还是在使用整数和浮点数(无结构)等简单数据类型时,我是否可以避免对齐错误?

编辑:如果有人稍后阅读此内容,我发现了一个包含有趣信息的类似问题:Mis-aligned pointers on x86

【问题讨论】:

  • x86 没有对齐要求。它有助于提高性能,但不是必需的。
  • 好的,所以我可以折腾字节数组和 uint32s floats doubles uint64s 并且永远不会有任何损坏?
  • 这不是一个特别具体的问题。正如我所说,就数据类型的对齐而言,您无能为力会导致错误。
  • 我的意思是,是否存在由于 x86 上的对齐问题而导致数据损坏的风险?编辑:哦,好吧,如果是这样就好了
  • 只是我读了其他人talking关于对齐问题,我想知道什么时候担心这个问题。您是否也了解 ARM (iPhone),不用担心那里的对齐是否安全?

标签: objective-c c clang memory-alignment


【解决方案1】:

通常,x86 架构没有对齐要求 [除了一些 SIMD 指令,如movdqa)。

但是,由于您正在尝试编写代码以导致此类异常...

有一个对齐检查异常位可以设置到x86标志寄存器中。如果您打开,未对齐的访问将生成一个异常,该异常将显示为 [至少在 linux 下] 为总线错误(即SIGBUS

请在此处查看我的答案:any way to stop unaligned access from c++ standard library on x86_64? 了解详细信息和一些生成异常的示例程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-06
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    • 2021-05-17
    • 2012-11-01
    相关资源
    最近更新 更多