让我们考虑这两行:
char input[1];
gets(input);
Run Code Online (Sandbox Code Playgroud)
假设输入是"测试".printf("%s \n",输入)=>"test"但是如果我使用调试器,我看到输入[0] ='t'没有输入[1] ......究竟发生了什么?
dwc*_*dwc 10
这是缓冲区溢出,fyi.为了好玩,添加char untouched[20];后char input[1];也打印untouched.不要使用gets(),使用fgets()或其他与边界检查.
调试器没有显示,input[1]因为没有这样的东西.您的char input[1];声明分配长度为1的数组,而不是从0到1的数组.
gets(s)从stdin读取一行到s指向的缓冲区,直到终止换行符或EOF,它替换为'\ 0'.不执行缓冲区溢出检查
http://linux.die.net/man/3/gets
执行gets时,输入被写入s指向的缓冲区.然后它添加一个\ 0.只有't'在输入缓冲区内.其余的,位于堆栈上的连续内存中.printf打印"test",因为它可以从s开始读取到第一个\ 0.但是"est\0"在缓冲区之外.
------
| t | input - Debugger only sees this position.
------
| e | Memory you are stepping onto. Trouble if it doesn´t belong to your proc.
| s |
| t |
| \0 |
------
Run Code Online (Sandbox Code Playgroud)
当你调试它时,输入只指向一个char,所以你可以看到.
重要的是要看一下"不检查缓冲区溢出是否已执行".这意味着如果为输入分配了内存,则获取函数并不在意.它将从您指示的点开始复制所有内容.如果您不小心,那么您的输入可以进入重要信息.在某些最糟糕的情况下,这将是您的函数的返回地址(您使用获取的地方)."只是犯"这个错误的人会说"wtf正在进行中".故意这样做的人会将您的返回地址指向特定部分,并执行位于那里的代码.