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

使用frozen.h的json_fprintf打印数组时出现段错误求助

问题分析与修复方案

核心问题点

  • 类型不匹配错误
    create_index_string_list函数参数声明为char *lst,但调用时传入的是int类型数组(如roll_array),类型不匹配触发未定义行为;同时函数返回值声明为char*,但实际要返回字符串数组(char**类型),内存分配与返回类型不匹配直接导致内存越界、段错误。

  • frozen.h格式符误用
    frozen.h中%M是自定义序列化函数的专属格式符,你直接传入数组和长度属于误用。int数组应使用%A格式符,字符串数组则需要配合自定义序列化函数使用%M。

  • 内存分配与资源管理缺失
    原代码未做内存分配失败的检查,也没有释放动态分配的内存,既会引发崩溃风险,也会导致内存泄漏。


修复后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "frozen.h"

// 修正返回类型与参数,去除无用参数lst
char **create_index_string_list(int len) {
    char **index_string_list = malloc(len * sizeof(char *));
    if (!index_string_list) return NULL; // 内存分配检查
    
    char index_str[3];
    for (int i = 0; i < len; i++) {
        sprintf(index_str, "%02d", i);
        size_t str_len = strlen("1:0") + strlen(index_str) + 1;
        char *str = malloc(str_len);
        if (!str) {
            // 分配失败时回滚已分配内存
            for (int j = 0; j < i; j++) free(index_string_list[j]);
            free(index_string_list);
            return NULL;
        }
        strcpy(str, "1:0");
        strcat(str, index_str);
        index_string_list[i] = str;
    }
    return index_string_list;
}

// 字符串数组的自定义序列化函数,配合%M使用
void serialize_string_array(struct json_out *out, va_list *args) {
    char **arr = va_arg(*args, char**);
    int len = va_arg(*args, int);
    json_array_start(out);
    for (int i = 0; i < len; i++) {
        json_string(out, arr[i]);
    }
    json_array_end(out);
}

int installation_info_graphs(int roll_array[], int roll_len, int pitch_array[], int pitch_len, int tn_array[], int tn_len, int snr_array[], int snr_len) {

    char **roll_index = create_index_string_list(roll_len);
    char **pitch_index = create_index_string_list(pitch_len);
    char **tn_index = create_index_string_list(tn_len);
    char **snr_index = create_index_string_list(snr_len);
    
    // 检查内存分配是否成功
    if (!roll_index || !pitch_index || !tn_index || !snr_index) {
        // 释放已分配资源
        if (roll_index) { for(int i=0;i<roll_len;i++) free(roll_index[i]); free(roll_index); }
        if (pitch_index) { for(int i=0;i<pitch_len;i++) free(pitch_index[i]); free(pitch_index); }
        if (tn_index) { for(int i=0;i<tn_len;i++) free(tn_index[i]); free(tn_index); }
        if (snr_index) { for(int i=0;i<snr_len;i++) free(snr_index[i]); free(snr_index); }
        return -1;
    }
    
    // 使用%A序列化int数组,%M配合自定义函数序列化字符串数组
    int ret = json_fprintf("/api/installation/inst_info_graphs.json", 
        "{roll: %A, roll_labels: %M,"
        "pitch: %A, pitch_labels: %M, true_north: %A, true_north_labels: %M,"
        "snr: %A, snr_labels: %M}", 
        roll_array, roll_len, serialize_string_array, roll_index, roll_len,
        pitch_array, pitch_len, serialize_string_array, pitch_index, pitch_len,
        tn_array, tn_len, serialize_string_array, tn_index, tn_len,
        snr_array, snr_len, serialize_string_array, snr_index, snr_len);
    
    // 释放所有动态分配的内存
    for(int i=0;i<roll_len;i++) free(roll_index[i]);
    free(roll_index);
    for(int i=0;i<pitch_len;i++) free(pitch_index[i]);
    free(pitch_index);
    for(int i=0;i<tn_len;i++) free(tn_index[i]);
    free(tn_index);
    for(int i=0;i<snr_len;i++) free(snr_index[i]);
    free(snr_index);
    
    return ret;
}

关键修复说明

  1. 修正create_index_string_list的类型错误,使其正确返回字符串数组指针,并增加内存分配失败的回滚逻辑。
  2. 针对frozen.h的格式规则:
    • %A用于序列化int数组,参数顺序为数组指针, 长度;
    • 字符串数组通过自定义序列化函数配合%M使用,参数顺序为序列化函数, 数组指针, 长度。
  3. 补充内存释放逻辑,彻底避免内存泄漏。

内容的提问来源于stack exchange,提问作者Cesar Rodriguez Serrano

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 16:02:45