所以我是C的新手,我遇到了这个警告发生的问题。警告意味着什么,我该如何解决它。 我写的代码在这里:
void main(void)
{
char* name = "";
int age = 0;
printf("input your name\n");
scanf("%s\n", name);
printf("input your age\n");
scanf("%d\n", age);
printf("%s %d\n", name, age);
}
答案 0 :(得分:12)
scanf
函数使用变量的地址将结果放入。
写scanf("%d", &someVar)
将传递someVar
变量的地址(使用&
一元运算符)。
scanf
函数会将一个数字放入该地址的内存中。 (包含你的变量)
当您撰写scanf("%d", age)
时,您会将age
变量的值传递给scanf
。它会尝试将一个数字放入地址0
的内存中(因为age
是0
),并且可怕地搞砸了。
您需要将&age
传递给scanf
。
您还需要为scanf
分配内存以将字符串读入name
:
char name[100];
scanf("%99s\n", name);
答案 1 :(得分:6)
问题在于这一行:
scanf("%d\n", age);
scanf需要指针参数 - 这是函数可以修改C中参数的唯一方法。为了解决这个问题,你需要:
scanf("%d\n", &age);
传递了ageof的地址,它现在是一个指针(指针是一个包含另一个内存区域的地址的变量)。
至于此:
char* name = "";
哎哟,超重,请 - 不要!好的,我需要解释一下。你已经要求指向一个字符类型的指针,但就每个人而言,你所拥有的只是一个字符,而不是整个字符串。没错,空间不够。为什么C允许你这样做?好吧,C基本上是可移植的汇编程序,因此你可以在内存中的任何地方编写代码(或者更确切地说,你可以尝试编译器不会反对,但操作系统可以并且可能会这样)。
你需要做的是使用malloc
读取内存分配以便分配一些空间,否则我可以输入一个大量的字符串,然后将它放在名称的地址上。
这虽然决不会导致基于堆栈的漏洞。什么,堆叠?是的。堆栈是一个FILO结构,每次调用一个函数时,都会在堆栈中为返回地址和函数参数添加空间,以及频繁的函数范围变量。
如果您不检查输入尺寸,这就成了问题。然后,我可以为您的堆栈写入大量值,包括可执行代码......请参阅Buffer Overflow。
那么,我听说你如何减轻这种影响,只是渴望不实施软件漏洞?您可以使用允许您指定缓冲区输入大小的函数并读入特定大小的缓冲区,然后从那里开始。而已。那很简单。
请参阅此问题:string reading in C。
答案 2 :(得分:1)
您应该写scanf("%d", &age)
,因为scanf
函数需要修改 age
的值,因此需要通过“地址”传递它不是“按价值”。
答案 3 :(得分:0)
这意味着它期望一个“int *”(即:一个指向整数的指针),但你给它“int”这是一个整数。要修复它,请添加&在scanf行中老化所以它变成了。
scanf(“%d \ n”,年龄);
答案 4 :(得分:0)
我假设它抱怨行scanf("%d\n", age);
问题是扫描f期望指向变量的指针而不是变量。
答案 5 :(得分:0)
警告意味着它所说的内容:编译器期望在int
调用中指向int
而不是scanf
。
快速修复:将age
替换为&age
,一切正常。
C按值传递所有参数,这意味着如果传递变量,则仅传递变量的值。接收函数可以根据需要修改该值,但原始值不会更改。要更改变量,需要以某种方式传递指向变量的值,在C中是指针。
要获取指向变量的指针,请在其前面添加&
。要使用变量指针,请使用*
为指针值添加前缀。
在这种情况下,您希望scanf
更改age
的值,因此您需要将指针传递给它。
答案 6 :(得分:0)
char* name = "";
name
指向一个或足够大的内存以容纳一个空字符。
scanf("%s\n", name);
您要求在此地址读取和存储未知数量的字符。 任何都可能发生。您必须确保name
拥有足够大的内存块的地址,以容纳 scanf()
可能读取的任何内容。
char twenty_bytes[20] = "";
scanf("%s\n", twenty_bytes);