0

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

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

程序不应该strncpy()a[7]='\0'大于5. 我得到输出为abcedefg. 我正在使用 gcc 编译器。

4

4 回答 4

2

数组的大小为 5 char a[5];,您在第 7 个位置进行分配,这是缓冲区溢出问题,并且代码的行为在运行时未定义。

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

两者都是错误的,您需要定义数组,如:

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

注意空字符"abcdefg"需要 8 个字符。\0

读取:字符串以空字符结尾,字面意思是 '\0' 字符

于 2013-04-11T06:17:39.940 回答
1

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

考虑一下“无色、绿色的想法疯狂地沉睡”,或者“打字机把大象传给了黑暗”。这些陈述中的任何一个在英语中都有意义吗?你会如何解释它们?这与 C 实现如何处理未定义行为的情况类似。

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

于 2013-04-11T07:07:59.077 回答
1

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

于 2013-04-11T06:20:14.733 回答
1

C 经常假设您知道自己在做什么,即使(尤其是)您做错了什么。数组没有边界,如果幸运并且您输入了未定义的内存位置并出现分段错误,您只会收到错误消息。否则,您将能够访问更改内存,无论结果如何。

于 2013-04-11T06:20:31.263 回答