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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 08:39:03