使用GCC 4.9.2-10 deb8u1编译时,字符指针scanf输入异常求助
问题解答:未初始化指针导致的异常输出
这问题本质是未初始化指针的非法内存访问,咱们来一步步理清楚:
首先看你原来的正常代码:sa和sb是栈上分配的固定大小数组,已经拥有了10字节的有效内存空间,scanf把输入字符串写入这些内存时,只要输入长度不超过数组容量,就能正常工作。
但当你把scanf的目标改成未初始化的char *s后,问题就出现了:
char *s;只是声明了一个指针变量,但它没有被初始化指向任何有效的内存地址。栈上的未初始化变量会保留随机的垃圾值,所以s此时指向的是一个完全不确定的内存位置。- 当执行
scanf("%s", s)时,scanf会尝试把输入的字符串写入s指向的内存区域——这属于未定义行为(C标准没有规定这种情况的结果)。你的程序没直接崩溃已经算“幸运”,但后续的行为完全不可预测。
你看到输出line (null) Hu的原因可能是:
- 未初始化的
s刚好被分配到了一个值为NULL(空指针)的内存位置,或者在后续的printf、第二个scanf操作中,s指向的内存被覆盖,导致printf识别它为无效的字符串指针,于是输出(null)。 - 而
sb是正常初始化的栈数组,内存有效,所以能正确输出输入的Hu。
正确的做法
要让指针s可以安全接收scanf的输入,你需要给它分配有效的内存:
- 方法1:用堆内存分配(记得用完释放)
#include <stdio.h> #include <stdlib.h> int main(){ char *s = malloc(10 * sizeof(char)); // 分配10字节内存 if (s == NULL) { printf("内存分配失败\n"); return 1; } char sb[10]; scanf("%s", s); printf("line\n"); scanf("%s", sb); printf("%s %s", s, sb); free(s); // 释放堆内存 return 0; }
- 方法2:让指针指向栈上的数组
#include <stdio.h> int main(){ char buf[10]; char *s = buf; // 指向栈上的有效内存 char sb[10]; scanf("%s", s); printf("line\n"); scanf("%s", sb); printf("%s %s", s, sb); return 0; }
重要提醒
未定义行为绝对不能依赖!哪怕这次程序没崩溃、输出了看似有规律的结果,换个编译器、换个系统或者仅仅是代码小改动,都可能导致程序崩溃、数据损坏等严重问题。一定要确保指针指向有效内存后再使用它。
内容的提问来源于stack exchange,提问作者szema
相关产品推荐
相关产品推荐

