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

更改读取输入大小时内存泄漏,headtail程序读取fail.txt无输出问题

问题根因

1. 核心崩溃原因:add_rows 函数野指针访问

扩容行存储区时,直接对新增的未初始化指针调用realloc,属于标准未定义行为,大概率直接导致程序崩溃无输出:
初始分配的field指针数组只有15个有效元素,调用add_rows扩容到25个元素后,下标15~24的指针都是未初始化的野指针,循环中对这些野指针执行realloc会直接触发非法内存访问。
data.txt能正常运行是因为前14行长度都超过初始分配的15字节,频繁触发行扩容逻辑,还没等触发行数扩容程序就已经完成输入读取输出;而fail.txt前几行很短,读取到第14行时触发行扩容,直接触发野指针访问崩溃。

2. 内存校验逻辑错误

allocate函数中分配完columns数组后,错误判断matrix->field是否为空,若columns分配失败无法被捕获,后续访问columns数组也会触发野指针。

3. 行计数逻辑缺陷

last_changed仅在遇到换行符\n时才递增,若输入文件最后一行没有以换行符结尾,最后一行不会被计入总数,当要求输出的行数等于实际行数时会触发输出校验失败,无内容返回。

4. 类型使用不合理

行数为整数,不该用double存储num_of_output_lines,存在潜在精度风险。


修复方案

1. 修复add_rows函数,新增行直接分配内存

bool add_rows(TMatrix* matrix) {
    int old_rows = matrix->rows;
    matrix->rows += 10;

    char** rebuf = realloc(matrix->field, matrix->rows * sizeof(char*));
    if (!rebuf) return false;
    matrix->field = rebuf;

    int* rebufl = realloc(matrix->columns, matrix->rows * sizeof(int));
    if (!rebufl) return false;
    matrix->columns = rebufl;

    // 新增行直接malloc,不要realloc野指针
    for (int i = old_rows; i < matrix->rows; i++) {
        matrix->field[i] = malloc(size * sizeof(char));
        if (!matrix->field[i]) {
            // 释放已分配的新行避免泄漏
            for (int j = old_rows; j < i; j++) free(matrix->field[j]);
            return false;
        }
        matrix->columns[i] = size;
    }
    return true;
}

2. 修复allocate函数的校验逻辑

TMatrix* allocate() {
    TMatrix* matrix = malloc(sizeof(TMatrix));
    if (!matrix) return NULL;

    matrix->field = malloc(size * sizeof(char*));
    if (!matrix->field) {
        free(matrix);
        return NULL;
    }
    matrix->rows = size;

    matrix->columns = malloc(size * sizeof(int));
    // 修正校验对象为columns
    if (!matrix->columns) {
        free(matrix->field);
        free(matrix);
        return NULL;
    }
    set_size(matrix);

    for (int i = 0; i < matrix->rows; i++) {
        matrix->field[i] = malloc(size * sizeof(char));
        if (!matrix->field[i]) {
            for (int j = 0; j < i; j++) free(matrix->field[j]);
            free(matrix->columns);
            free(matrix->field);
            free(matrix);
            return NULL;
        }
    }
    return matrix;
}

3. 修复行计数逻辑,处理无结尾换行的文件

在load函数的while循环结束后增加如下代码:

// 处理最后一行无换行的场景
if (actual_column > 0) {
    matrix->field[actual_row][actual_column] = '\0';
    last_changed += 1;
}

4. 修正行数类型

将output函数的num_of_output_lines参数改为int类型,main函数中对应修改为:

int num_of_output_lines = atoi(argv[argc - 1]);

内容的提问来源于stack exchange,提问作者Ghost123

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 00:27:04