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

时间:2011-10-19 08:24:30

标签: c memory-management dynamic-memory-allocation

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

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

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

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

4 个答案:

答案 0 :(得分:4)

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

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

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

例如,假设您声明:

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

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

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

一个类比:“标志说我只允许在光线为绿色的时候过马路。我穿过红色,什么都没发生。为什么车没撞到我?” (有些语言不会让使汽车撞到你.C不是其中之一。)

答案 1 :(得分:1)

  

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

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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

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