C语言实现8-7位文件压缩解压时触发Bad file descriptor错误
错误根因定位
fgetc()返回-1且报Bad file descriptor(对应系统错误码EBADF)的核心本质是:传入的FILE*流不支持读操作、流已被关闭、或流指针本身是无效野指针。结合ASCII MSB压缩的作业场景,按触发概率从高到低排错如下:
1. 解压时打开压缩文件的模式错误(最高发)
- 若打开压缩生成的二进制文件时误用了只写模式(
"w"/"wb"/"a"等),对只写权限的流调用读操作会直接触发EBADF。 - 跨平台注意:Windows环境下读写二进制文件必须加
b模式标记,读压缩文件必须用"rb",写解压输出文件必须用"wb",文本模式下的换行符转换会破坏二进制压缩数据,也可能诱发流状态异常。
2. 压缩流程结束后流状态失效
- 若同进程内先执行压缩再执行解压,压缩写完文件后未调用
fclose()关闭写流、也未通过rewind()/fseek()将文件偏移重置到文件头,甚至在compress8to7内部提前关闭了压缩文件的流,后续直接把失效的FILE*传给解压函数读,就会触发该错误。 - 验证方法:调用解压函数前先检查
ferror(input_file_8to7)和feof(input_file_8to7)的返回值,确认流未进入错误/结束状态,同时确认流指针未被提前释放。
3. 未做fopen返回值校验,空指针传入fgetc
- 若压缩阶段因为路径错误、权限不足没成功生成压缩文件,解压阶段
fopen读不存在的文件会返回NULL。如果没做空指针校验直接把NULL传给fgetc,会触发内存访问错误,部分环境下也会报坏文件描述符。 - 所有文件打开操作必须加校验,参考代码:
FILE* input_file_8to7 = fopen("compressed.out", "rb"); if (input_file_8to7 == NULL) { perror("Failed to open compressed file"); exit(EXIT_FAILURE); }
4. 内存越界破坏了文件指针
- 若压缩逻辑中做7bit比特拼接时存在缓冲区溢出,踩内存覆盖了
input_file_8to7指针本身的存储值,导致传入fgetc的是野指针,也会触发该错误。可以在调用解压函数前打印文件指针的值,和fopen返回的原始指针对比,确认指针值没有被意外修改。
快速定位技巧:单独写一个最小测试程序,单独用
"rb"模式打开压缩生成的文件,逐字节调用fgetc读取,如果能正常读到完整内容,说明问题出在main函数的文件打开、关闭、指针传递流程,和uncompress8to7的比特拼接解压逻辑无关。
内容的提问来源于stack exchange,提问作者Saar Weinberg
相关产品推荐
相关产品推荐

