【发布时间】:2023-03-28 00:29:01
【问题描述】:
我目前正在阅读 Expert C Programmign - Deep C Secrets。在第 164 页作者解释 Bus Error 和 Segmentation fault 的地方,他展示了这行代码
union {
char a[10];
int i;
} u ;
int * p = ( int * ) &(u.a[1]);
*p = 17; /* the misaligned addr in p causes a bus error */
上面的代码是假设触发总线错误,但是当我运行它时,它运行良好,没有任何错误。作者给出了以下解释
这会导致总线错误,因为数组/整数联合确保字符数组“a”也位于整数的合理对齐地址,因此“a+1”绝对不是。然后我们尝试将 4 个字节存储到一个仅针对单字节访问对齐的地址中。一个好的编译器会警告未对齐,但它不能发现所有出现的情况。
我对上述语句的理解是,char 是 1 字节,我们试图将 4 字节的 int 放置在 char a[10] 的索引上,因此会发生总线错误(不确定是否我的理解是对是错)
我的问题是为什么上面的代码不会导致总线错误。
注意:我不是 CS 学生,简单的解释会有所帮助。
注意:已经提出了一个与此问题类似的问题,但仅针对上述代码块。
【问题讨论】:
-
“我有这本书说我不能在 30 公里/小时的区域内以 100 公里/小时的速度开车。但是我无论如何都做了并且没有被逮捕。为什么我没有被逮捕?”
-
如果
a是一个指针(例如char *a;),我可以更真实地看到总线错误和段错误。在任何一种情况下,您都有i大约占用可用存储空间的 1/2,但是如果在这种情况下您将i更改为有效内存块之外的值 - 总线错误/段错误。 -
您使用什么架构和操作系统?如果您使用的是英特尔,那么您将不会注意到任何差异(最坏的情况是会慢几纳秒以获得额外的内存获取)。如果您在 linux 上使用 ARM/PowerPC/MIPS 等,那么您可能会发现内核已被配置为执行自动“修复”。查找“/proc/cpu/alignment”以获取有关如何控制内核行为和查看修复计数的详细信息。
-
在这个问题上有这么多不知情的答案和 cmet...
标签: c segmentation-fault bus-error