尽管缓冲区长度为0且编译器发出警告,scanf()仍可工作.到底是怎么回事? [英] scanf() works despite 0-length buffer and compiler warning. What is going on?
问题描述
我的编译器(clang)显示以下消息:
My compiler (clang) shows this message:
11:17:warning: format specifies type 'char *' but the argument has
type 'char (*)[0]' [-Wformat]
scanf("%s", &name);
~~ ^~~~~
1 warning generated.
来自以下代码(问候程序):
from the following code (greetings program):
/*
* Program: gretting2.c
* Utility: Display a greeting with your name.
* Author: Adrián Garro.
*/
#include <stdio.h>
int main () {
char name[0];
printf("-------------------\n");
printf("Write your name: \n");
printf("-------------------\n");
scanf("%s", &name);
printf("------------------------------------\n");
printf("Hello %s, nice to meet you\n",name);
printf("------------------------------------\n");
}
实际上发生了什么,我该如何解决?
What is actually going on, and how can I fix it?
推荐答案
您的代码表现出未定义的行为".这意味着任何事情都可能发生.一切.
Your code exhibits "undefined behavior." This means anything could happen. Anything.
您正在将一个零长度数组传递给scanf()
.此外,您没有在格式字符串中传递数组长度.这会导致缓冲区溢出漏洞(在零长度目标数组的情况下始终如此).
You are passing a zero-length array to scanf()
. Also, you are not passing the array length in the format string. This results in a buffer overflow vulnerability (always, in the case of a zero-length target array).
您需要这样的东西:
char name[51];
scanf("%50s", name);
请注意,%50s
现在指定目标数组的大小(减少一个,为空终止符留出空间!),这避免了缓冲区溢出.您仍然需要检查scanf()
的返回值,以及输入name
是否实际上过长(您不希望在不告知用户的情况下截断用户的输入).
Note the %50s
now specifies the size of the target array (less one, to leave room for the null terminator!), which avoids buffer overflow. You still need to check the return value of scanf()
, and whether the input name
is actually too long (you wouldn't want to truncate the user's input without telling them).
如果您使用的是Linux,请签出名为valgrind
的工具.它是一个运行时内存错误检测器(除其他外),有时可以为您捕获这样的错误(以及不太明显的错误,这是要点).对于许多C程序员来说,它是必不可少的.
If you're on Linux, check out the tool called valgrind
. It is a runtime memory error detector (among other things), and can sometimes catch errors like this for you (and much less obvious ones, which is the main point). It's indispensable for many C programmers.
这篇关于尽管缓冲区长度为0且编译器发出警告,scanf()仍可工作.到底是怎么回事?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!