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

CS50 2023 Pset4 Recover程序内存错误排查求助

CS50 2023第4周Recover习题集内存错误排查

你的代码存在两个核心问题,直接导致了内存错误:


1. 未关闭已打开的输出文件,引发资源泄漏

当检测到新的JPEG文件头时,程序直接调用fopen打开新的输出文件,但之前已经打开的输出文件没有被关闭。操作系统对进程可打开的文件句柄数量有限制,这种重复打开不关闭的行为会造成资源泄漏,触发内存错误。

2. 可能对空指针执行fclose操作

如果输入文件中没有任何JPEG数据,outputFile会一直保持NULL状态。程序最后执行fclose(outputFile)时,相当于尝试关闭一个空指针,这属于未定义行为,必然引发内存错误。


修正后的代码

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

typedef uint8_t BYTE;

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        printf("Wrong usage\n");
        return 1;
    }

    FILE *inputFile = fopen(argv[1], "r");
    if (inputFile == NULL)
    {
        printf("File cannot be opened\n");
        return 1;
    }

    BYTE buffer[512];
    int counter = 0;
    FILE *outputFile = NULL;
    char filename[8];

    size_t bytesRead;
    while ((bytesRead = fread(buffer, sizeof(BYTE), 512, inputFile)) != 0)
    {
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
        {
            // 打开新文件前,先关闭之前的输出文件(如果存在)
            if (outputFile != NULL)
            {
                fclose(outputFile);
            }
            sprintf(filename, "%03i.jpg", counter);
            outputFile = fopen(filename, "w");
            counter++;
        }
        if (outputFile != NULL)
        {
            // 写入实际读取到的字节数,避免最后一次写入越界
            fwrite(buffer, sizeof(BYTE), bytesRead, outputFile);
        }
    }

    // 关闭最后一个输出文件(仅当它被打开过)
    if (outputFile != NULL)
    {
        fclose(outputFile);
    }
    fclose(inputFile);

    return 0;
}

关键修改说明

  • 每次打开新输出文件前,先检查并关闭之前的输出文件,避免资源泄漏
  • 关闭输出文件前增加非空判断,防止对空指针执行关闭操作
  • 记录每次fread实际读取的字节数,用该数值执行fwrite,确保最后一次写入的是实际读取到的数据,避免缓冲区越界

内容的提问来源于stack exchange,提问作者Berra Eylül Toprak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 08:26:28