C语言调用fread()读取PNG文件头时触发segfault段错误求助
问题排查与修复方案
核心问题原因
- fopen返回值未校验:调用
fopen()打开文件后没有判断是否成功,如果文件路径错误、权限不足、文件不存在时,fopen()会返回NULL,后续fread()传入空指针作为文件流参数,直接触发段错误,这是你遇到问题的根因。 - 调试输出小问题:你当前的
printf("%s", "HIHI")没有追加换行符,stdout默认是行缓冲模式,如果没手动调用fflush(stdout),程序崩溃时缓冲区内容可能没来得及输出,会干扰问题定位,建议调试输出末尾加\n或者手动刷新缓冲区。 - 潜在逻辑隐患:
PNG_FILE_FINGERPRINT定义为const char数组,0x89在有符号char的编译环境下会被识别为负数,memcmp实际按无符号字节做比较,最好修改为const unsigned char类型避免比较逻辑出错。 - 遗漏资源释放:当前代码没有主动关闭打开的文件流,会造成文件描述符泄漏。
修复后的代码
#include <stdio.h> #include <string.h> // 此处补充你定义PNG类型的自定义头文件 // 修改为unsigned char避免有符号char溢出问题 const unsigned char PNG_FILE_FINGERPRINT[8] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a }; PNG * PNG_open(const char *filename, const char *mode) { FILE *fp = fopen(filename, mode); // 新增fopen失败判断,避免空指针传入后续接口 if (fp == NULL) { // 可打开下方注释打印具体错误原因:perror("打开文件失败"); return NULL; } char buffer[8] = {0}; // 仅需要读取8字节,缓冲区开8即可 printf("HIHI\n"); // 加换行自动刷新行缓冲 size_t len = fread(buffer, 1, 8, fp); fclose(fp); // 用完关闭文件流,避免资源泄漏 if (len != 8 || memcmp(buffer, PNG_FILE_FINGERPRINT, 8) != 0) { return NULL; } // 此处后续补充PNG结构体初始化逻辑,当前示例保留原返回逻辑 return NULL; }
内容的提问来源于stack exchange,提问作者Tim Chen
相关产品推荐
相关产品推荐

