1.重复fclose导致的系统dump

fclose() 不能重复调用
对同一个 FILE* 调用 一次 fclose 是正确的,但如果你:

  • 已经 fclose(fp);
  • 又再次 fclose(fp); 或使用该 fp

那么行为是 未定义行为(Undefined Behavior, UB)

1. 程序立刻崩溃(最常见)

因为第二次 fclose() 会尝试访问一个已经被释放的内部结构(FILE 结构体),导致:

  • 段错误(segmentation fault)
  • 总线错误(bus error)
  • 内存访问异常

2. 静默失败,看似没事(但内存已损坏)

有些 libc 会忽略部分操作,但实际上 FILE 已被释放,内部堆结构可能已损坏,为后续崩溃埋雷。

多次创建删除任务,并且每次该任务都会重复fclose,最终在某次任务结束后删除任务导致系统立即dump,在trace32上的表现为asm,栈溢出

3. 破坏堆内存(Heap Corruption)

fclose() 内部需要释放缓冲区,如果再次释放:

  • 双重释放(double free)
  • freelist 被破坏
  • 程序后续随时崩溃

4. 影响其他 FILE 结构,导致难以调试的 bug

可能破坏 stdio 内部链表,引发:

  • fwrite 错误
  • printf 崩溃
  • 其他文件关闭失败

❗为什么会导致未定义行为?

因为 fclose() 完成后:

  • 内部 FILE 对象被释放(free)
  • 缓冲区被释放
  • 文件描述符关闭
  • FILE* 指针指向的内存变成“垃圾”,不可再访问

再次 fclose(fp) 就像对已经 free 的指针做 free —— 属于 double free


🪪 如何避免?

✔ 1. fclose 后把指针置为 NULL

fclose(fp);

fp = NULL;

✔ 2. 调用前判断是否为 NULL

if (fp != NULL) {

    fclose(fp);

    fp = NULL;

}

✔ 3. 一个函数只负责一个 fclose,不要多处关闭


📌 示范代码:重复 fclose 会导致崩溃

FILE* fp = fopen("a.txt", "r");

fclose(fp);   // OK

fclose(fp);   // 未定义行为,常常崩溃


📘 总结

同一个 FILE* 重复调用 fclose() 是未定义行为,常导致崩溃或内存破坏。fclose 后应把指针设为 NULL(fclose不会自发的将文件指针设为空)并在下次关闭同一文件时进行文件空指针判断。

注意区分文件句柄与文件指针

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐