C语言中json_object_put()触发段错误的原因及修复方案
问题原因与修复方案
段错误原因
核心问题是内存双重释放,json-c通过引用计数管理对象生命周期:
- 调用
json_object_object_add(jsonmain,"Data",jsontmp)时,jsonmain会自动增加jsontmp的引用计数,相当于接管了该子对象的所有权。 - 你提前调用
json_object_put(jsontmp),将jsontmp的引用计数减至0,直接释放了它的内存。 - 后续调用
json_object_put(jsonmain)时,jsonmain会尝试递归释放所有子对象,此时访问已被释放的jsontmp内存,触发段错误。
修复后的代码
无需手动释放已添加到父对象的子对象,仅释放顶层jsonmain即可,它会自动递归清理所有子对象。同时补充内存分配、序列化的错误检查,避免其他潜在异常:
char* createjsonstatusstring() { json_object *jsonmain, *jsontmp; const char *conststring; char *string; jsonmain = json_object_new_object(); if (!jsonmain) return NULL; jsontmp = json_object_new_object(); if (!jsontmp) { json_object_put(jsonmain); return NULL; } json_object_object_add(jsontmp,"test",json_object_new_string("Beispiel")); json_object_object_add(jsontmp,"test2",json_object_new_string("Beispiel2")); json_object_object_add(jsonmain,"Data",jsontmp); conststring = json_object_to_json_string_ext(jsonmain,JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY); if (!conststring) { json_object_put(jsonmain); return NULL; } string = malloc(strlen(conststring)+1); if (!string) { json_object_put(jsonmain); return NULL; } strcpy(string,conststring); json_object_put(jsonmain); // 仅释放顶层对象,递归清理所有子对象 return string; }
额外注意事项
- 所有添加到父对象的子对象,其生命周期由父对象负责,不要手动调用
json_object_put释放。 - 任何内存分配、序列化操作都要做失败检查,避免空指针访问引发其他崩溃。
内容的提问来源于stack exchange,提问作者Christian
相关产品推荐
相关产品推荐

