访问动态分配的arrays的越界元素/没有SegFault

我正在用C开发一个程序,它使用一组链表(一个原始哈希表)作为数据类型来表示某些日期信息。 该数组有12个元素,对应于一年中的月份,每个月都有一个包含数据节点的链表。

我开发了使用此数据类型的模块,它工作正常。 我后来发现我正在访问超出界限的数组元素(例如,通过索引12而不是11来访问第12个元素)。 但该计划始终如一地顺利进行。 我从未收到过分段错误。 我已经纠正了编码错误。 有人可以解释为什么访问越界元素不会导致段错误吗?

这不是第一次发生。 我创建了一个动态分配的多维数组,为了测试,我试图访问越界元素。 该程序运行良好,产生了准确的结果,并且在大多数情况下没有出错。 我唯一一次实现一个,我不得不尝试访问大量的越界元素。

(这些程序目前是用于测试的Windows控制台应用程序。我正在使用MinGW进行编译。如果有帮助,我可以包含代码。)

在C中,访问其边界之外的数组是未定义的行为

这意味着任何事情都可能发生,包括程序的行为与您预期的一样。

C语言不需要对数组访问进行边界检查,并且大多数C编译器都不实现它。

例如,假设您声明:

int before; int array[10]; int after; 

这些存储在内存中的顺序是未定义的,但假设它们按照它们声明的顺序连续存储。 如果您尝试访问array[-1] ,则可以before访问。 如果您尝试访问array[10] ,则可以after访问。

程序员的负担是避免访问超出其边界的数组。 或者在arrays之前和/或之后可能没有任何分配。

一个类比:“标志说我只允许在光线为绿色的时候穿过街道。我穿过红色,什么也没发生。为什么没有车撞到我?” (有些语言可以你的车撞到你身上.C不是其中之一。)

有人可以解释为什么访问越界元素不会导致段错误吗?

这是Undefined Behavior,它没有segfault。 在Linux上,您可以在Valgrind下运行程序来捕获此类错误。

SegFaults是OS生物。 当进程尝试访问不属于它的内存并且不是C语言的一部分时,它们会被抛出。 在C中,访问out of bounds元素只是未定义的行为,这意味着它可能会失败,而它可能不会。 例如,如果内存分配器提供的内存块大于您对arrays的要求,则操作系统将不关心您是否超出限制,因为您将访问属于您的进程的内存。 在这种情况下,您只是在程序中遇到错误。

通过索引超出数组范围来访问数据是未定义的行为。 在大多数情况下(特别是动态分配的内存),访问数据“靠近”(不太远离界限),arrays不会因各种原因而出现段错误。 内存可以以舍入的块分配,大于您请求的内容,或者“malloc”实现可能会放置一些任意的簿记信息等。最终结果是该内存块被映射,但可能包含从垃圾到重要预订的数据保持信息。 不要依赖这种行为。