C语言 为什么此程序中没有显示段错误?



在我的理解中,当程序因尝试访问不可用的内存而崩溃时,就会发生分段错误。我知道第一个程序(A.c(是错误的,因为sizeof(a(是4字节* 5 = 20字节。第二个程序(B.c(是错误的,因为无穷循环。当我运行 A.out 时,我没有收到错误,只是结果不正确(结果也不一致(。但是当我运行 B.out 时,我遇到了分段错误。

我希望 A 具有与 B 相同的分段错误,因为它们都访问超出范围的内存数据。我最好的猜测是,也许int a[5] = {1, 2, 3, 4, 5};原因。有人可以告诉我为什么吗?

交流电

int main() {
int a[5] = {1, 2, 3, 4, 5};
unsigned total = 0;
printf("size of a is %lun", sizeof(a));
printf("total was %dn", total);
for (int j = 0; j < sizeof(a); j++) {
total += a[j];
}
printf("sum of array is %dn", total);
}

不列颠哥伦比亚省

int main() {
int a[20];
for (int i = 0; ; i++) {
a[i] = i;
}
}

澄清一下:分段错误不是因为不断检查您的代码是否越界而出现的东西。相反,它是 CPU 级别的一种机制,涉及告诉 CPU 应该在 RAM 的哪个区域发生某些事情并捕获违反此情况的情况。RAM 的这个区域也不完全是代码或数据的大小。因此,在某些情况下,访问超出范围的日期是访问 CPU 可能访问的内存,例如,在您访问的变量或数组之后存储的另一个变量或数组的索引过高,甚至是一些未使用的内存,因为允许的内存块可能具有向上舍入以匹配某些对齐边界的大小。

我不认为int a[5] = {1, 2, 3, 4, 5};会导致您的应用程序不失败。如果省略= {1, 2, 3, 4, 5}您仍然定义了要访问的有效内存块,则其内容尚未定义。

您是否期望 A 失败,因为您使用sizeof(a)而不是sizeof(a)/sizeof(int)?假设int为 4 个字节,这将导致 A 访问的内存量是允许的 4 倍。这一切很可能仍在堆栈内存中,您不会在其中导致分段错误。在 B 中,你有一个无限循环,这导致它解决堆栈大小的问题,这将导致分段错误。

两者都是未定义的行为。UB 表示从 C 的角度来看无法确定操作的结果。

访问未分配的内存可能但不一定要导致段错误。

但是试图理解这两个片段

一个。您可以访问离数组边界不远的内存。操作系统不会阻止程序访问此区域。什么也没发生。

b. 最终您到达受操作系统保护的内存。 段错误发生。

最新更新