为什么这个数组不会出错?

时间:2013-04-11 06:15:41

标签: c arrays char

我有一个程序,我希望它崩溃,但事实并非如此。你能告诉我原因吗。

char a[5];
strncpy(a,"abcdefg",7);
a[7] = '\0';
printf("%s\n",a);

该程序不应该在strncpy()a[7]='\0'处崩溃,而是大于5的数组大小。我输出为abcedefg。我正在使用gcc编译器。

4 个答案:

答案 0 :(得分:2)

数组的大小为5 char a[5];,并且您在第7个位置分配buffer overrun问题,并且代码的行为在运行时未定义。

strncpy(a,"abcdefg",7);
a[7] = '\0';

两者都错了,你需要定义如下数组:

#defined size 9  // greater then > 7
char a[size];

通知"abcdefg"需要为\0 null char添加8个字符。

阅读:a string ends with a null character, literally a '\0' character

答案 1 :(得分:1)

在您的示例中,您的程序可以访问超出a(数组的起始地址)加5的内存,因为程序的堆栈可能更高。因此,尽管代码有效,但理想情况下它是未定义的行为。

答案 2 :(得分:1)

C经常假设你知道自己在做什么,甚至(特别是)你做错了什么。没有数组的界限,如果您的幸运并且您已进入未定义的内存位置并且出现分段错误,则您只会收到错误。否则,您将能够访问更改内存,无论结果如何。

答案 3 :(得分:1)

您无法对未定义的行为进行定义,因为您正在尝试声明它应该崩溃通常不会崩溃的未定义行为的另一个示例是 int x = INT_MAX + 1; int x = 0; x = x++ + ++x; 。如果只是巧合,这些可能会在您的系统上运行。这并不能阻止他们对其他系统造成严重破坏!

考虑“无色,绿色的想法疯狂地睡觉”,或者“打字机将大象传给黑暗”。这些陈述中的任何一个都用英语有意义吗?你怎么解释他们?这与C实现如何处理未定义的行为类似。

让我们考虑如果您让我在我的纸箱中放入42个鸡蛋,可以存储至少 12个鸡蛋会发生什么。容器肯定有限,但你坚持认为它们都适合那里。我发现容器只能储存12个鸡蛋。你不会知道剩下的30个鸡蛋会发生什么,所以行为是不确定的。