CS50 Pset4 Recover程序内存错误:输出文件关闭问题咨询
解决Recover照片程序的文件未关闭问题
Valgrind检测到的23,128字节可访问内存,本质是你打开的输出文件output未被正确关闭,导致文件句柄关联的内核缓存资源未释放。以下是必须添加fclose(output);的关键位置:
- 切换输出文件时关闭前一个:当检测到新的JPG文件签名时,若之前已经打开了一个输出文件,必须先关闭它再打开新文件。这是因为每张JPG对应一个独立的输出文件,写完前一张就该释放资源。
- 程序退出前关闭最后一个文件:当存储卡数据读取完毕(循环结束),要检查是否还有未关闭的
output文件,若有则关闭。 - 异常退出分支也要处理:如果程序有提前退出的逻辑(比如读取失败、内存分配错误等),每个退出点都要先判断
output是否为非空指针,再执行关闭操作。
典型修复示例(伪代码)
FILE *input = fopen("card.raw", "r"); FILE *output = NULL; unsigned char buffer[512]; int img_count = 0; char img_name[8]; // 逐块读取存储卡数据 while (fread(buffer, 1, 512, input) == 512) { // 检测到新JPG头部 if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0) { // 关闭之前打开的输出文件(如果存在) if (output != NULL) { fclose(output); } // 生成新的文件名并打开输出文件 sprintf(img_name, "%03d.jpg", img_count++); output = fopen(img_name, "w"); } // 若当前有打开的输出文件,写入数据块 if (output != NULL) { fwrite(buffer, 1, 512, output); } } // 循环结束后,关闭最后一个打开的输出文件 if (output != NULL) { fclose(output); } fclose(input);
关键注意点
- 调用
fclose前必须判断output是否为NULL:如果fopen失败(比如磁盘满),output会是空指针,直接关闭会导致崩溃。 - 不要遗漏任何打开文件的分支:只要执行了
output = fopen(...)且成功,就必须对应一次fclose。
内容的提问来源于stack exchange,提问作者khaledwaleed
相关产品推荐
相关产品推荐

