C语言字符串输入代码段出现段错误,请求排查问题原因
段错误原因分析:char*与字符数组在scanf输入时的差异
先看你给出的出问题的代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> main() { char *str; int len; printf("Enter the expression: \n"); scanf("%[^\n]", &str); printf("%s\n", str); len = strlen(str); printf("%d\n", len); }
出现段错误有两个核心原因:
- 指针未分配有效内存:
char *str;只是声明了一个字符指针,但它并没有指向任何合法的可写内存空间,此时指针的值是随机的,指向的可能是系统保护的内存区域。当scanf尝试往这个随机地址写入数据时,直接触发内存访问违规,导致段错误。 - scanf参数传递错误:你传给
scanf的是&str,这是指针变量本身的地址(类型是char**),但%[^\n]格式符要求的是char*类型的参数。这会导致scanf把输入的字符串直接写到指针变量str占用的内存里,彻底破坏指针的原有值,后续使用str时必然访问非法内存。
而改用字符数组(比如char str[100];)时,数组在声明时就已经在栈上分配了固定大小的合法可写内存空间,scanf可以直接往这块内存里写入数据,自然不会触发段错误。
修正方案
有两种常见的解决方式:
- 使用字符数组(简单直接):
#include <stdio.h> #include <string.h> int main() { char str[100]; // 分配足够大的栈内存 int len; printf("Enter the expression: \n"); scanf("%[^\n]", str); // 直接传数组名(数组名等价于首元素地址) printf("%s\n", str); len = strlen(str); printf("%d\n", len); return 0; }
注意:要确保数组大小足够容纳输入的字符串,避免缓冲区溢出。
- 动态分配内存:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char *str = malloc(100 * sizeof(char)); // 分配堆内存 if (str == NULL) { perror("malloc failed"); return 1; } int len; printf("Enter the expression: \n"); scanf("%[^\n]", str); // 传指针本身 printf("%s\n", str); len = strlen(str); printf("%d\n", len); free(str); // 释放堆内存 return 0; }
这种方式需要记得用free释放内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者sam tenison
相关产品推荐
相关产品推荐

