C语言使用realpath()传路径参数读文件出现段错误如何解决
问题原因
代码触发段错误、无法实现预期功能是多个低级错误叠加导致,和编译器、系统环境无关:
- 未做任何返回值校验:
realpath()在传入路径不存在、无路径遍历权限时会直接返回NULL;fopen()在目标文件不存在、无读权限、打开失败时也会返回NULL。代码直接将可能为NULL的指针传入后续操作,访问空指针会直接触发段错误。 - 文件操作逻辑完全错误:你用
"r"只读模式打开文件,却调用fprintf()试图向只读流写入内容;且fprintf(fptr, "%s")缺少格式符对应的字符串参数,属于C语言未定义行为,必然引发内存访问异常。另外你的需求是读取文件内容打印到终端,fprintf是写入类函数,根本不适合做读操作。 - 未做资源回收:当
realpath()第二个参数传NULL时,返回的路径字符串是动态分配的堆内存,用完需要手动free();打开的文件流用完也需要fclose(),否则会出现内存泄漏、文件描述符泄漏。
修复方案
按以下步骤调整即可:
- 给所有系统调用增加空指针校验,出错时打印对应错误信息后退出
- 替换错误的写文件逻辑:打开文件后逐字符/逐块读取内容,输出到标准输出流
stdout - 所有资源用完后主动释放,包括动态分配的路径内存、打开的文件流
修复后的可运行代码:
#include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { if (argc < 2) { printf("Usage: %s <path>\n", argv[0]); return 1; } // 解析真实路径,增加错误校验 char *fullpath = realpath(argv[1], NULL); if (fullpath == NULL) { perror("realpath failed"); return 1; } // 只读打开文件,增加错误校验 FILE *fptr = fopen(fullpath, "r"); if (fptr == NULL) { perror("fopen failed"); free(fullpath); // 异常退出分支也要提前释放已分配内存 return 1; } // 逐字符读取文件内容,打印到终端 int ch; while ((ch = fgetc(fptr)) != EOF) { putchar(ch); } // 统一回收资源 fclose(fptr); free(fullpath); return 0; }
补充说明
你测试用的路径/var/log/message在Fedora 36上默认不存在,系统日志默认路径为/var/log/messages,且普通用户默认没有该文件的读权限,初期测试可以先用自己用户目录下的普通文本文件验证功能,避免权限、路径问题干扰调试。
内容的提问来源于stack exchange,提问作者tuatara
相关产品推荐
相关产品推荐

