我的一位朋友,昨天向我发送了此代码:
int main()
{
int n = 3 ;
int a[n];
for (int i = 0; i <= 5; ++i)
{
a[i] = i;
printf("%d ", a[i]);
}
return 0;
}
当我第一次看到这个时,我以为会出现索引错误,因为,在for循环中,我们有一个[3] = 3,而对于索引4,5相同,并且我们只为3个内存块分配内存但随后他将输出发送给我:
0 1 2 3 4 5
我们俩都不知道为什么会这样,有人可以帮忙吗?
答案 0 :(得分:3)
在C中,没有自动范围检查。 C只是让您访问您想访问的内容。
因此,即使您的数组仅保留3个整数,C仍然允许您访问a[3]
,a[4]
甚至a[100]
。没有运行时检查,没有编译时检查。有几种“静态代码分析器”可以(帮助)检查您的代码中是否存在此类问题,但C编译器不必(通常也不需要)。
当您越界访问时,它称为UB,即未定义的行为。在这种情况下,可能会发生任何事情。也许程序会崩溃。也许它会按照您的期望去做。也许它将做一些“奇怪的事情”,例如打印奇怪的输出,否则将继续运行。我们不能告诉...
因此,避免越界访问是您的全部责任。没有C ...
注意:尽管C不包括用于越界访问的运行时检查,但是系统上可能存在其他情况(在某些情况下)可以/将检测到非法内存访问。但这是系统功能,而不是C功能。
答案 1 :(得分:2)
我们正在为3个内存块分配内存
不,您有10个内存块,
int n = 10;
int a[n];
有效索引范围是0...9
。
答案 2 :(得分:1)
数组的大小为10:程序正确。你能更精确吗?
答案 3 :(得分:1)
a[n]
实际上是指向数组第一个地址的指针。 C中没有范围检查。程序正在执行的操作是访问最初未分配给它的内存。这样做时,您的程序可能无法正常工作。
在这种情况下,程序正在访问未分配给阵列但分配给程序(但未被使用)的内存,这就是为什么不引发任何错误的原因。