使用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; }
关键修复说明
- 修正
create_index_string_list的类型错误,使其正确返回字符串数组指针,并增加内存分配失败的回滚逻辑。 - 针对frozen.h的格式规则:
%A用于序列化int数组,参数顺序为数组指针, 长度;- 字符串数组通过自定义序列化函数配合
%M使用,参数顺序为序列化函数, 数组指针, 长度。
- 补充内存释放逻辑,彻底避免内存泄漏。
内容的提问来源于stack exchange,提问作者Cesar Rodriguez Serrano
相关产品推荐
相关产品推荐

