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

使用json-c的json_tokener_parse解析JSON时出现段错误,求排查原因

分析你的段错误原因与修复方案

你的代码触发段错误的核心原因,以及几个关键问题我帮你梳理清楚了:

核心崩溃原因

json_tokener_parse要求传入以空字符'\0'结尾的C字符串,但你通过mmap映射的JSON文件原始内容并不自带这个终止符。当解析函数试图读取超出文件映射区域的内存时,就会访问非法地址,直接触发段错误。

除此之外,代码里还有几个会加剧或引发崩溃的问题:

  • 变量名冲突:你定义了struct stat stat;,变量名stat和系统结构体名重名,虽然C语言允许,但容易造成混淆,甚至在部分编译环境下引发异常。
  • 未检查系统调用返回值:open、fstat、mmap都可能调用失败(比如文件不存在、权限不足),如果忽略错误继续使用无效值(比如mmap返回MAP_FAILED无效指针),后续操作必然崩溃。
  • 权限不匹配:你以O_RDONLY只读打开文件,但mmap时指定了PROT_WRITE可写权限,这会导致mmap调用失败,返回无效指针。

修复后的完整代码

#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <json-c/json.h>

int main() {
    const char *path = "file.json";
    int fd = open(path, O_RDONLY);
    // 检查文件是否打开成功
    if (fd == -1) {
        perror("Failed to open file");
        return EXIT_FAILURE;
    }

    struct stat file_stat; // 重命名变量避免与结构体名冲突
    int ret = fstat(fd, &file_stat);
    if (ret == -1) {
        perror("Failed to get file stat");
        close(fd);
        return EXIT_FAILURE;
    }

    size_t size = file_stat.st_size;
    // 权限匹配:只读打开文件,mmap仅用PROT_READ
    void *addr = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
    if (addr == MAP_FAILED) {
        perror("Failed to mmap file");
        close(fd);
        return EXIT_FAILURE;
    }

    // 分配内存并添加空终止符,满足json_tokener_parse的要求
    char *json_str = malloc(size + 1);
    if (!json_str) {
        perror("Failed to allocate memory");
        munmap(addr, size);
        close(fd);
        return EXIT_FAILURE;
    }
    memcpy(json_str, addr, size);
    json_str[size] = '\0'; // 手动添加字符串终止符

    json_object *jobj = json_tokener_parse(json_str);
    if (!jobj) {
        fprintf(stderr, "Failed to parse JSON content\n");
        free(json_str);
        munmap(addr, size);
        close(fd);
        return EXIT_FAILURE;
    }

    // 这里可以添加你的JSON处理逻辑,比如打印解析结果
    printf("JSON parsed successfully: %s\n", json_object_to_json_string(jobj));

    // 释放所有资源,避免内存泄漏
    json_object_put(jobj);
    free(json_str);
    munmap(addr, size);
    close(fd);

    return EXIT_SUCCESS;
}

关键修复点说明

  1. 添加空终止符:通过malloc分配比文件大小多1字节的内存,复制映射内容后手动添加'\0',确保解析函数能正确识别字符串边界。
  2. 修正变量名:将struct stat stat改为struct stat file_stat,避免与系统结构体名冲突。
  3. 完善错误检查:对所有系统调用的返回值做校验,出错时及时释放资源并退出,避免无效操作。
  4. 权限匹配:只读打开文件时,mmap使用PROT_READ权限,同时改用MAP_PRIVATE(只读场景下更安全,无需共享映射)。
  5. 资源清理:添加了munmap、close、free以及json_object_put(释放json-c创建的对象),彻底避免内存泄漏。

内容的提问来源于stack exchange,提问作者BODDU MANOHAR REDDY

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:13:53