使用fgets操作字符串数组时触发Segmentation Fault(段错误)求助
段错误原因与修复方案
问题根源
你的代码存在两个核心问题:
- 内存分配逻辑错误:
char **array是指向指针数组的指针,你直接分配了300字节(3个100字符的空间),但没有为每个指针元素分配有效的内存地址。此时*(array)是一个未初始化的野指针,fgets尝试向野指针指向的地址写入数据,直接触发段错误。 - 缺少错误检查:没有判断
fopen和malloc的返回值,若文件打开失败或内存分配失败,后续操作会引发未知错误。
修复方案
方案一:正确分配指针数组+每个字符串空间
先为指针数组分配空间,再逐个为每个字符串分配内存:
#include <stdio.h> #include <stdlib.h> int main(void) { FILE *file = fopen("test.txt", "r"); if (!file) { // 检查文件是否打开成功 perror("fopen failed"); return 1; } // 分配3个char*的指针数组空间 char **array = malloc(sizeof(char*) * 3); if (!array) { // 检查内存分配是否成功 perror("malloc array failed"); fclose(file); return 1; } // 为每个指针分配100字节的字符串存储空间 for (int i = 0; i < 3; i++) { array[i] = malloc(sizeof(char) * 100); if (!array[i]) { perror("malloc string failed"); // 释放已分配的内存 for (int j = 0; j < i; j++) { free(array[j]); } free(array); fclose(file); return 1; } } // 读取文件第一行到数组第0个元素 if (fgets(array[0], 100, file) == NULL) { perror("fgets failed"); } else { printf("%s\n", array[0]); } // 释放内存:先释放每个字符串,再释放指针数组 for (int i = 0; i < 3; i++) { free(array[i]); } free(array); fclose(file); return 0; }
方案二:分配二维数组(更简洁)
直接分配一个3行100列的二维字符数组,避免多级指针的复杂操作:
#include <stdio.h> #include <stdlib.h> int main(void) { FILE *file = fopen("test.txt", "r"); if (!file) { perror("fopen failed"); return 1; } // 分配3个长度为100的字符数组空间 char (*array)[100] = malloc(sizeof(*array) * 3); if (!array) { perror("malloc failed"); fclose(file); return 1; } if (fgets(array[0], 100, file) == NULL) { perror("fgets failed"); } else { printf("%s\n", array[0]); } free(array); fclose(file); return 0; }
关键说明
- 方案一适合需要动态调整每个字符串长度的场景,方案二更适合固定字符串长度的情况。
- 任何涉及文件操作和内存分配的代码,都必须检查返回值,避免因资源获取失败导致的崩溃。
内容的提问来源于stack exchange,提问作者Jman4546
相关产品推荐
相关产品推荐

