You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将文本行存入字符串数组时调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 16:35:23