以下C代码有 char str [3]; ,它应该只存储3个字符?
然而,当我编译并运行程序时,它似乎可以存储更多。
我只得到"分段错误"我输入" ABCDEFGHIJKLMNOPQRSTUVWXY"这显然超过3个字符。
我可以知道为什么吗?
p / s:是的,我知道"得到"功能很危险,不建议使用。我只是好奇为什么它可以保留更多的数据。user@box:~/c$ cat -n putsgets.c
1 #include <stdio.h>
2
3 int main()
4 {
5 char str[3];
6 puts("Enter a line of text: ");
7 gets(str);
8 puts("\nYou entered: ");
9 puts(str);
10 return 0;
11 }
user@box:~/c$
user@box:~/c$ gcc putsgets.c -o putsgets
putsgets.c: In function ‘main’:
putsgets.c:7:2: warning: implicit declaration of function ‘gets’ [-Wimplicit-function-declaration]
gets(str);
^~~~
/tmp/cclFmZp2.o: In function `main':
putsgets.c:(.text+0x1f): warning: the `gets' function is dangerous and should not be used.
user@box:~/c$
user@box:~/c$ ./putsgets
Enter a line of text:
ABC
You entered:
ABC
user@box:~/c$ ./putsgets
Enter a line of text:
ABCD
You entered:
ABCD
user@box:~/c$
下一步
user@box:~/c$ ./putsgets
Enter a line of text:
ABCDE
You entered:
ABCDE
user@box:~/c$ ./putsgets
Enter a line of text:
ABCDE
You entered:
ABCDE
user@box:~/c$ ./putsgets
Enter a line of text:
ABCDEF
You entered:
ABCDEF
user@box:~/c$ ./putsgets
Enter a line of text:
ABCDEFGHIJKLMN
You entered:
ABCDEFGHIJKLMN
最后,当我输入ABCDEFGHIJKLMNOPQRSTUVWXY(最后一行)时发生了分段错误
user@box:~/c$ ./putsgets
Enter a line of text:
ABCDEFGHIJKLMNOPQRSTU
You entered:
ABCDEFGHIJKLMNOPQRSTU
user@box:~/c$ ./putsgets
Enter a line of text:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
You entered:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
Segmentation fault
user@box:~/c$ ./putsgets
Enter a line of text:
ABCDEFGHIJKLMNOPQRSTUVWXY
You entered:
ABCDEFGHIJKLMNOPQRSTUVWXY
Segmentation fault
user@box:~/c$
答案 0 :(得分:5)
您可能知道,C不会检查内存安全性。但是,像valgrind这样的公用事业确实可以帮助解决这个问题。
您的操作系统为您的程序提供了比它请求的内存更多的内存,并且只有当您走出其中一个内存时才会发现分段错误。
How does a segmentation fault work internally (kernel/hardware)?
答案 1 :(得分:1)
它的未定义行为,因为C和C ++不检查数组绑定。
答案 2 :(得分:1)
在C中,您可以向数组添加比声明更多的cbaracters,因为不会执行运行时检查。你所做的就是缓冲区溢出。
如果此类代码通过网络连接接受数据,则黑客可以利用它来运行任意机器代码!
但是,在java和C#中执行运行时检查并且缓冲区溢出会导致OutOfRangeExeption。这些检查由java虚拟机执行。
好问题,并保持好奇心。