如何在 macbook pro(Intel 64 位处理器)上用 C 语言演示内存未对齐错误
How to demonstrate a memory misalignment error in C on a macbook pro (Intel 64 bit processor)
为了理解 C 内存对齐或其他术语(数据结构对齐?),我试图编写导致对齐错误的代码。让我了解这个的最初原因是我正在编写数据解析代码来读取通过网络接收的二进制数据。数据包含一些 uint32、uint64、浮点数和双精度数,我想确保它们不会因我的解析代码错误而损坏。
由于未对齐而导致某些问题的失败尝试:
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 所以 clang)
我想我的 processor/machine/setup 支持未对齐读取,所以上面的代码没有任何问题。
如果由于代码未考虑对齐而导致 uint32_t 的解析失败会怎样?有没有办法让它在现代英特尔 64 位系统上失败?或者在使用整数和浮点数(无结构)等简单数据类型时,我可以避免对齐错误吗?
编辑:如果有人稍后阅读这篇文章,我发现了一个包含有趣信息的类似问题:Mis-aligned pointers on x86
通常情况下,x86 架构没有对齐要求[除了一些 SIMD 指令,例如 movdqa
)。
但是,由于您试图编写代码来导致此类异常...
有一个 对齐检查异常 位可以设置到 x86 标志寄存器中。如果打开,未对齐的访问将生成一个异常,该异常将 [至少 linux 下] 显示为总线错误(即 SIGBUS
)
在这里查看我的回答: 了解详细信息和一些生成异常的示例程序。
为了理解 C 内存对齐或其他术语(数据结构对齐?),我试图编写导致对齐错误的代码。让我了解这个的最初原因是我正在编写数据解析代码来读取通过网络接收的二进制数据。数据包含一些 uint32、uint64、浮点数和双精度数,我想确保它们不会因我的解析代码错误而损坏。
由于未对齐而导致某些问题的失败尝试:
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 所以 clang)
我想我的 processor/machine/setup 支持未对齐读取,所以上面的代码没有任何问题。
如果由于代码未考虑对齐而导致 uint32_t 的解析失败会怎样?有没有办法让它在现代英特尔 64 位系统上失败?或者在使用整数和浮点数(无结构)等简单数据类型时,我可以避免对齐错误吗?
编辑:如果有人稍后阅读这篇文章,我发现了一个包含有趣信息的类似问题:Mis-aligned pointers on x86
通常情况下,x86 架构没有对齐要求[除了一些 SIMD 指令,例如 movdqa
)。
但是,由于您试图编写代码来导致此类异常...
有一个 对齐检查异常 位可以设置到 x86 标志寄存器中。如果打开,未对齐的访问将生成一个异常,该异常将 [至少 linux 下] 显示为总线错误(即 SIGBUS
)
在这里查看我的回答: