将文本行存入字符串数组时调用strcpy触发Segmentation Fault的问题
段错误原因分析与修复方案
核心问题
- 野指针写入:你用
malloc(MAXLINES)给stringList分配的是10个字符指针的存储空间,但每个指针根本没指向有效的可写内存——都是野指针。strcpy往野指针地址写数据,直接触发段错误。 - 命令行参数越界:
argv[2]是错的,命令行里argv[0]是程序本身的名字,用户传的文件名应该是argv[1],读argv[2]会越界,搞不好提前就出问题。 - getline初始化混乱:你给
lineBuf分配了MAXLINELENGTH的内存,却把lineBufSize设成0,getline会忽略你手动分配的内存,后续内存管理容易乱。 - 行数没做限制:没检查
lineCount是不是超过MAXLINES,要是文件行数超过10,stringList直接越界访问,又是未定义行为。
修复后的完整代码
#include<stdio.h> #include<stdlib.h> #include<string.h> #define MAXLINELENGTH 20 #define MAXLINES 10 int fileToStringList(char* fileName, char** stringList){ char* lineBuf = (char*) malloc(MAXLINELENGTH); size_t lineBufSize = MAXLINELENGTH; // 匹配手动分配的内存大小 int lineCount = 0; ssize_t lineSize; FILE* fp = fopen(fileName, "r"); if(!fp){ fprintf(stderr, "Failed to open file\n"); exit(EXIT_FAILURE); } // 限制行数不超过MAXLINES,避免数组越界 while((lineSize = getline(&lineBuf, &lineBufSize, fp)) >= 0 && lineCount < MAXLINES){ // 为当前行分配足够内存,包含字符串终止符 stringList[lineCount] = (char*) malloc(lineSize + 1); if(!stringList[lineCount]){ fprintf(stderr, "Out of memory\n"); exit(EXIT_FAILURE); } strcpy(stringList[lineCount], lineBuf); // 可选:去掉换行符,根据需求调整 stringList[lineCount][strcspn(stringList[lineCount], "\n")] = '\0'; lineCount++; } fclose(fp); free(lineBuf); // 释放getline用的缓冲区 return lineCount; } int main(int argc, char* argv[]){ // 检查参数数量是否正确 if(argc != 2){ fprintf(stderr, "Usage: %s <filename>\n", argv[0]); exit(EXIT_FAILURE); } char* fileName = argv[1]; // 分配存放指针的数组,注意要乘sizeof(char*) char** stringList = (char**) malloc(MAXLINES * sizeof(char*)); if(!stringList){ fprintf(stderr, "Out of memory\n"); exit(EXIT_FAILURE); } int lineCount = fileToStringList(fileName, stringList); printf("Number of lines: %d\n", lineCount); // 释放所有分配的内存,避免泄漏 for(int i=0; i<lineCount; i++){ free(stringList[i]); } free(stringList); return 0; }
关键修复点说明
- 给
stringList的每个元素单独分配内存,解决野指针问题。 - 修正命令行参数的读取逻辑,增加参数检查,避免非法访问。
- 调整
getline的初始化参数,让内存管理逻辑一致。 - 限制读取的行数不超过
MAXLINES,防止数组越界。 - 添加了内存释放代码,避免内存泄漏。
- 把错误信息输出到标准错误流
stderr,符合程序规范。
内容的提问来源于stack exchange,提问作者Oscar Stenqvist
相关产品推荐
相关产品推荐

