我正在看这个简单的程序。我的理解是,尝试修改超出最大索引的内存地址的值应该导致分段错误。但是,以下代码运行没有任何问题。我甚至能够打印出所有6个数组索引0-> 6
main()
{
int i;
int a[3];
for(i=0; i<6; i++)
a[i] = i;
}
但是,当我将for循环更改为
时for(i=0; i<7; i++)
并执行该程序,它将是段错误。 这几乎在我看来它是由malloc完成的某种额外填充。 为什么在第6个索引(s + 6)之后只发生?这种行为会在更长/更短的数组中发生吗?请原谅我的愚蠢程度如此低级的java程序员:)
答案 0 :(得分:6)
在我看来,这似乎是由malloc完成的某种额外填充。
你没有调用malloc()。您在堆栈内存中将a
声明为3个整数的数组,而malloc()使用堆内存。在这两种情况下,访问最后一个元素之后的任何元素(在这种情况下为第三个,a[2]
)是未定义的行为。当它完成堆内存时,通常会导致分段错误。
答案 1 :(得分:4)
好吧,malloc
没有做到,因为你没有打电话给malloc
。我的猜测是,额外的三次写入足以咀嚼你的帧指针和你的堆栈指针,但不是通过你的返回地址(但是第七次写入)。当您访问越界内存时,您的程序不会保证崩溃(尽管还有其他语言可以保证它),但不能保证不崩溃。这是什么未定义的行为:不可预测。
答案 2 :(得分:2)
正如其他人所说,访问超出其限制的数组是不确定的行为。那会发生什么?如果访问不应访问的内存,则取决于内存的位置。
通常(但一般来说,细节可能因系统和编译器而异),可能会发生以下主要情况:
我可能已经忘记了可能发生的一些问题,但那些是IMO,如果你写的超出数组范围就会发生最常见的事情。
答案 3 :(得分:1)
这取决于可用的可用内存,如果可用的可用内存少,那么它将给出分段错误,否则它将使用额外的内存来存储数据,并且它不会给出分段错误。不需要malloc因为数组本身分配内存。
在您的系统中,内存仅适用于6个整数,当您尝试访问下一个内存(无法访问或说不可用)时,它会产生分段错误。