printf或scanf上的分段错误

printf或scanf上的分段错误,c,printf,scanf,C,Printf,Scanf,我有一个代码,不明白它为什么会崩溃,我从过去的帖子中知道它与不可访问的内存有关,我想,但我初始化了输入变量 #include <stdio.h> #include <stdlib.h> char *getInfo() { char input[1000]; scanf("%s", input); return input; } int main() { char *x; x = getInfo(); printf("%s\n", x);

我有一个代码,不明白它为什么会崩溃,我从过去的帖子中知道它与不可访问的内存有关,我想,但我初始化了输入变量

#include <stdio.h>
#include <stdlib.h>
char *getInfo() {
   char input[1000];
   scanf("%s", input);
   return input;
}
int main() {
   char *x;
   x = getInfo();
   printf("%s\n", x);
   return 0;
}
当我在gdb中运行并回溯程序时,它会说。。。主要错误。c:11 当我在给出输入后在第11行中断时,请尝试打印变量,打印输入给我“\000 x29”,打印x给我0x0。我知道0x0意味着它是空的,我想\000也意味着空的,但我不明白为什么,当我扫描输入时,空值不应该被替换吗?

您的函数getInfo返回局部变量输入的地址。但是当函数返回时,该变量被删除,因此指针变得无效。解决这个问题的常规方法是将数组作为参数传递到函数中

char *getInfo(char *input) {
   scanf("%s", input);
   return input;
}
在呼叫端:

char input[1000];
char *x = getInfo(input);
当然,在您的情况下,我只需将对scanf的呼叫移至main:

还请注意,您对scanf的调用不安全,因为scanf读取的输入可能超过缓冲区的容量。另外,我对getInfo的非常简单的更改也有一个缺点,就是您不能传递长度。通常,应该将指针传递给缓冲区和缓冲区的大小。这样可以确保函数不会溢出缓冲区

对于更安全的变体,在你的情况下,你也可以考虑其中的一条:

scanf("%999s", input);
fgets(input, 1000, stdin);

这回答了你的问题吗?您正在将输入数组创建为函数中的局部变量,并尝试返回指向它的指针。但是,局部变量在函数执行后超出范围,这导致指向垃圾的指针。一个快速的解决方法是使变量为静态的,但这会使数组具有静态生存期,您可能不希望这样。或者,您可以在main中创建数组,并将其传递给要更新的函数。另一个选项是使用malloc动态分配数组,然后在完成后释放它,例如在main的末尾。我只需执行scanf%s,input;->建议扫描%999s,输入;或fgets演示如何确保函数不会溢出缓冲区。。否则,您也可以编写代码。
scanf("%999s", input);
fgets(input, 1000, stdin);