数组中的元素太多! 。?!
很抱歉,如果这是一个noob问题:(数组中的元素太多! 。?!
片的C代码
int array[5];
int cnt;
for(cnt = 0; cnt <= 10; cnt+=1)
{
array[cnt] = cnt;
}
应该给一个错误,没有正确工作正常 但是,为什么是它似乎!? - 在第一行中定义了一个超过双倍大小的数组(11),你甚至可以稍后访问数组[5到10],这让我感到困惑,当你定义数组[4或更小]时它会停止工作, ...
提前致谢。
它可能会与您的特定编译器和计算机一起工作,但您不应该依赖它。
根据C语言规范,您的代码的行为是undefined。这意味着它可能做你想做的事,或者它可能会导致你的电脑崩溃,或者可能导致demons to fly out your nose。
与高级语言(如Java和C#)不同,C相信您并不会对数组边界执行显式检查。你应该是负责任的,而不是在阵列的边界之外。
“但是为什么呢?”
因为这就是C的方式。
在运行时不检查数组边界。
这就是
这只是“的C法”,“作品”,如果你的“作品”的定义是“还没有崩溃”的代名词。
一旦运行数组的末尾,就会覆盖软件不期望的内存并破坏堆。你的软件可能会继续运行,但它会非常不稳定!
取决于堆栈内存的打包方式。此外,它会高兴地覆盖这些值,甚至读取它们,但很可能你正在破坏堆栈。
你所看到的是未定义的行为,由您访问具有无效索引的数组引起的。未定义的行为意味着任何事情都可能发生,包括您的程序看起来正常工作。
C中的数组在运行时不会被检查。换句话说,你可以“定义”一个大小为N的数组,并且愉快地访问数组边界的末尾。如果你离开数组的末尾,那么你会在栈(或堆)上的某个地方垃圾。
一旦你在某处丢弃了内存,你的程序可能会崩溃。这些崩溃可能很难追查到,因为它们可能会远离实际上超出数组末尾的地方。
通常当你声明在C数组,最好使用某种恒定或#定义标记数组的大小:
#define MAX_ELEMENTS 10
int array[MAX_ELEMENTS];
int cnt;
for(cnt = 0; cnt < MAX_ELEMENTS; cnt+=1) {
array[cnt] = cnt;
}
如果经过MAX_ELEMENTS在数组赋值,你可能覆盖cnt的值。您可能会覆盖其他一些变量。全部取决于编译器和代码结构。还要注意在for循环中使用<符号。 C数组基于0,因此您必须使用小于或小于或等于检查。
我只想指出,所有这些确实没有定义。 您的示例在本示例中“有效”,因为这两个变量都位于堆栈中。那就是cnt的地址就在数组的末尾。当cnt达到cnt == 5 时语句数组[cnt] = cnt;不会写入专用于该阵列的内存中,而是在其之后,cnt的地址所在的内存中写入。它只是运气,它不会改变你的柜台。 当cnt> 5时没有内存垃圾,它只会写入“stack void”(不知道正确的单词)。
另一个例子来说明这一点:
int main(int ac,char **av)
{
int a[5];
int cnt;
int cnt2=3;
for(cnt=0;cnt<7;cnt++) {
a[cnt]=cnt;
printf("%d %d %d\n", a[cnt], cnt, cnt2);
}
}
输出:
0 0 3
1 1 3
2 2 3
3 3 3
4 4 3
5 5 5
6 6 5
循环的最后两个写操作之后的[]重写栈数据,并且可以产生非常混乱误差。在这种情况下,cnt2被丢弃。
C中的数组边界是不一定是在运行时检查。该标准让执行者可以自由选择或不选择 - 这是undefined的一部分。在使用胖指针的实现中,示例可能确实会导致某种错误。
用于鼻子恶魔守卫的+1! – RBerteig 2009-04-27 20:48:34
@Rerteig:我不认为“断层”(defenstration不是一个词)意味着你认为它的意思。在英语中,这将是通过窗口投掷某人/某物的行为。 http://en.wikipedia.org/wiki/Defenestration – 2009-04-27 21:55:16
确实是一个错字,但这个词的选择是故意的。我正在寻找一些与“恶魔”合作的东西,这种东西具有适当的意外驱逐感。这是一个延伸,可能超过了比喻的突破点;-) – RBerteig 2009-04-27 23:30:30