使用malloc与双指针时触发Segmentation fault问题求助
问题分析与解决方案
兄弟,你遇到的Segmentation Fault完全是因为野指针非法访问内存导致的,咱们一步步拆解问题:
核心问题:未初始化的野指针
看你代码里的这行:
char *chr;
你只声明了一个字符指针,但没有给它分配任何有效的内存空间——它现在是个「野指针」,指向内存里一个随机的、你无权访问的地址。当你执行scanf("%s", chr)时,程序试图把输入的字符串写到这个非法地址里,操作系统会立刻触发内存保护机制,直接抛出Segmentation Fault,这就是程序连n的输入都没完成就崩溃的原因。
其他次要问题(暂时没触发,但也得注意)
char pchr;这个变量声明了但完全没用到,属于冗余代码;malloc之后没有检查返回值,如果内存分配失败会得到NULL指针,后续操作也会出问题;
修正后的代码示例
这里给你两种可靠的修正方案,选适合你需求的就行:
方案1:用固定大小的字符数组(适合输入长度可控的场景)
#include <stdio.h> #include <stdlib.h> int main() { int n; // 声明固定大小的字符数组,在栈上分配合法内存 char chr[100]; // 限制输入长度为99(留1位存字符串结束符'\0'),防止缓冲区溢出 scanf("%99s", chr); scanf(" %d", &n); // 分配二维数组的行指针,必须检查malloc是否成功 char **table = (char **)malloc(n * sizeof(char*)); if (table == NULL) { perror("malloc failed"); return 1; } char *chr2 = chr; // 这里只是让chr2指向chr的起始地址,没问题 // 后续使用完table后记得释放内存 free(table); return 0; }
方案2:动态分配内存(适合输入长度不确定的场景)
如果不确定用户输入的字符串长度,可以先读取输入再动态分配内存:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { int n; char *chr = NULL; size_t buf_size = 0; // 用getline读取输入,会自动分配足够的内存(POSIX标准函数) if (getline(&chr, &buf_size, stdin) == -1) { perror("getline failed"); return 1; } // 去掉getline读取的换行符 chr[strcspn(chr, "\n")] = '\0'; scanf(" %d", &n); char **table = (char **)malloc(n * sizeof(char*)); if (table == NULL) { perror("malloc failed"); free(chr); // 记得释放之前分配的内存 return 1; } char *chr2 = chr; // 释放所有动态分配的内存 free(chr); free(table); return 0; }
关键注意事项
- 永远不要使用未初始化的指针进行读写操作;
- 使用
scanf读取字符串时一定要限制长度,避免缓冲区溢出; - 动态分配内存后必须检查返回值,使用完记得释放,防止内存泄漏。
内容的提问来源于stack exchange,提问作者Nejc Ahtik
相关产品推荐
相关产品推荐

