我有一个程序,我希望它崩溃,但事实并非如此。你能告诉我原因吗。
char a[5];
strncpy(a,"abcdefg",7);
a[7] = '\0';
printf("%s\n",a);
该程序不应该在strncpy()
或a[7]='\0'
处崩溃,而是大于5
的数组大小。我输出为abcedefg
。我正在使用gcc编译器。
答案 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个鸡蛋会发生什么,所以行为是不确定的。