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

C语言分类算法仅生成单个分区文件且执行后崩溃问题排查

问题排查:classificacao_interna_Func函数异常分析

问题描述

实现的classificacao_interna_Func函数预期按文件总大小生成每个含M条记录的分区文件,但目前仅生成一个分区文件,程序执行后崩溃;调用的tamanho_arquivo函数在此场景返回记录数异常(实际1000条返回977,实际10条返回0),但该函数在搜索、排序场景正常工作。


1. tamanho_arquivo函数关闭传入文件指针,导致后续操作失效

代码中tamanho_arquivo函数最后调用了fclose(arquivo),但classificacao_interna_Func是将已打开的arq指针传入该函数,执行后arq被关闭,后续对arq的所有操作(fseek、fread等)均为无效操作,直接导致:

  • 文件读取失败,记录数计算异常
  • 后续循环无法读取更多数据,仅生成一个分区
  • 访问已关闭的文件指针触发崩溃

修复方法:
移除tamanho_arquivo中的fclose(arquivo),恢复文件指针到开头后返回,由调用方负责关闭文件:

int tamanho_arquivo(FILE *arquivo) {
    if (arquivo == NULL) {
        perror("Erro ao abrir o arquivo");
        return -1;
    }

    fseek(arquivo, 0, SEEK_END);
    long tamanho_total = ftell(arquivo); 

    if (tamanho_total == -1) {
        perror("Erro ao obter o tamanho do arquivo");
        return -1;
    }

    int num_registros = tamanho_total / tamanho_registro();
    fseek(arquivo, 0, SEEK_SET); // 恢复指针位置,不影响调用方后续操作
    return num_registros;
}

同时在classificacao_interna_Func函数末尾添加fclose(arq);,关闭自身打开的文件。

2. 使用!feof(arq)作为循环条件导致读取异常

feof()仅在读取操作尝试读取文件末尾之后才会返回非零值,直接用!feof(arq)作为循环条件会导致最后一次读取失败后仍执行循环体,引发:

  • 分配内存但读取失败,v[i]指向未初始化内存
  • reg计数错误,导致外层循环无法正常退出

修复方法:
通过检查fread的返回值控制循环:

while (i < M) {
    v[i] = (TFunc*)malloc(sizeof(TFunc));
    if (fread(v[i], sizeof(TFunc), 1, arq) != 1) {
        free(v[i]); // 读取失败,释放已分配内存
        break;
    }
    i++;
    reg++;
}

3. 函数未返回值,触发未定义行为

classificacao_interna_Func声明为int类型,但函数末尾无return语句,程序执行完该函数后会出现未定义行为,表现为崩溃或其他异常。

修复方法:
在函数末尾添加返回值,同时关闭打开的文件:

NUM_PARTITIONS = qtdParticoes;
fclose(arq);
return qtdParticoes;

4. 修改栈数组大小的逻辑隐患

代码中当i != M时将M = i,但v是栈上声明的数组TFunc *v[M];,其大小由函数调用时的初始M值决定,修改M变量不会改变数组实际大小。若初始M远大于实际读取的i值,虽不会直接出错,但逻辑存在冗余;若i为0,后续排序、写文件、free循环都会基于M=0执行,属于不合理分支。

修复建议:
改用临时变量存储实际读取的记录数,避免修改原M值:

int actual_count = i;
// 后续排序、写文件、free操作均使用actual_count

5. 文件指针定位冗余且易出错

读取原文件时,每次循环都调用fseek(arq, (reg) * t, SEEK_SET);,但fread会自动推进文件指针,该操作不仅冗余,还可能因reg计数错误导致定位偏差。

修复建议:
移除循环内的fseek,依赖fread自动管理指针位置(需确保tamanho_arquivo已将指针恢复到文件开头)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 15:51:05