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

从文件读取数据到堆内存的函数问题:堆未成功写入数据

问题分析与修复

核心问题:文件指针未重置

你用fgetc遍历完整个文件后,文件内部指针已经移到了文件末尾(EOF),后续调用fscanf直接读取到EOF,根本读不到任何数据,堆内存里自然是malloc初始化的默认值(刚好显示0.000)。

解决:计数完成后调用rewind(read),把文件指针重置到文件开头,这样后续fscanf才能正常读取数据。

次要问题:计数逻辑错误

你现在统计的是空白字符(空格、制表符、换行)的数量,但成绩数量应该是空白数+1(比如90 85 70有2个空格,对应3个成绩)。当前逻辑会导致malloc的内存比实际需求少1个,可能引发越界或漏读。

无效代码:return后的free永远不会执行

free(heap)写在return heap之后,程序执行到return就直接返回了,这行代码永远不会被执行,属于无效代码,直接删掉即可。

修正后的代码

double *read_data(char const *file_name, int *ptr_cnt)
{
    FILE *read = fopen(file_name, "r");
    if (read == NULL)
    {
        return NULL;
    }
    int count = 0;
    char ch;
    // 处理空文件场景,同时避免连续空白导致计数虚高
    int first_char = fgetc(read);
    if (first_char != EOF)
    {
        count = 1; // 至少存在一个成绩
        ungetc(first_char, read); // 把读取的第一个字符放回文件流
        while ((ch = fgetc(read)) != EOF)
        {
            if (ch == ' ' || ch == '\t' || ch == '\n')
            {
                // 跳过连续空白,只在空白后出现有效数字时计数
                char next_ch = fgetc(read);
                if (next_ch != ' ' && next_ch != '\t' && next_ch != '\n' && next_ch != EOF)
                {
                    count++;
                    ungetc(next_ch, read);
                }
            }
        }
    }
    *ptr_cnt = count;

    // 重置文件指针到开头
    rewind(read);

    double *heap = malloc(sizeof(double) * count);
    if (heap == NULL) { // 新增malloc失败检查,避免后续崩溃
        fclose(read);
        return NULL;
    }
    double num = 0.0;
    int i;
    for (i = 0; i < count && fscanf(read, "%lf", &num) != EOF; i++)
    {
        heap[i] = num;
    }
    fclose(read);
    return heap;
}

额外优化说明

  1. 新增malloc空指针检查,避免内存分配失败引发后续错误
  2. 优化计数逻辑,解决连续空白字符导致成绩数量统计虚高的问题
  3. 处理了空文件的特殊场景,避免计数错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 10:05:21