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

C语言使用realpath()传路径参数读文件出现段错误如何解决

问题原因

代码触发段错误、无法实现预期功能是多个低级错误叠加导致,和编译器、系统环境无关:

  • 未做任何返回值校验:realpath() 在传入路径不存在、无路径遍历权限时会直接返回NULL;fopen() 在目标文件不存在、无读权限、打开失败时也会返回NULL。代码直接将可能为NULL的指针传入后续操作,访问空指针会直接触发段错误。
  • 文件操作逻辑完全错误:你用"r"只读模式打开文件,却调用fprintf()试图向只读流写入内容;且fprintf(fptr, "%s") 缺少格式符对应的字符串参数,属于C语言未定义行为,必然引发内存访问异常。另外你的需求是读取文件内容打印到终端,fprintf是写入类函数,根本不适合做读操作。
  • 未做资源回收:当realpath()第二个参数传NULL时,返回的路径字符串是动态分配的堆内存,用完需要手动free();打开的文件流用完也需要fclose(),否则会出现内存泄漏、文件描述符泄漏。
修复方案

按以下步骤调整即可:

  1. 给所有系统调用增加空指针校验,出错时打印对应错误信息后退出
  2. 替换错误的写文件逻辑:打开文件后逐字符/逐块读取内容,输出到标准输出流stdout
  3. 所有资源用完后主动释放,包括动态分配的路径内存、打开的文件流

修复后的可运行代码:

#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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 02:24:27