You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用Jansson库构建REST请求JSON的内存释放正确性问询

嘿,这个问题问到点子上了——Jansson的引用计数内存管理初上手确实容易让人疑惑,我来给你理清楚:

1. 仅调用一次json_decref(json_body)完全足够!

你代码里的写法是没问题的,原因在于Jansson的引用计数转移机制

  • 当你调用json_object_set_new往父对象里添加子节点时,这个函数会自动接管子节点(比如json_string(sentString)创建的字符串节点)的引用所有权。
  • 也就是说,你不需要手动调用json_decref去释放那些子字符串节点,当你最后对顶层的json_body调用json_decref时,它会递归地对所有子节点执行引用计数递减操作,直到所有相关内存都被正确释放。

2. Jansson创建JSON请求的正确内存释放姿势

总结下来,核心原则就是谁拥有引用,谁负责释放,具体可以分这几种情况:

  • 使用带_new后缀的容器操作函数(比如json_object_set_newjson_array_append_new):这类函数会直接获取子节点的所有权,无需手动释放子节点,只需最后释放顶层的JSON对象/数组即可。
  • 使用不带_new的函数(比如json_object_set):这时候你需要先手动增加子节点的引用计数(用json_incref),或者在不需要子节点时手动调用json_decref释放,否则会出现内存泄漏或者悬空指针。
  • 临时创建的未加入容器的JSON节点:如果你创建了一个JSON节点但没有把它加入到任何父容器中,那必须手动调用json_decref释放它,比如:
    json_t *tmp_str = json_string("temp");
    // 没有把tmp_str加到任何父对象里
    json_decref(tmp_str); // 必须手动释放
    

回到你的代码,你用的是json_object_set_new,所有子节点的所有权都已经交给了json_body,所以最后一次json_decref(json_body)就能彻底释放所有相关内存,完全不用担心遗漏。

内容的提问来源于stack exchange,提问作者Omer Anisfeld

火山引擎 最新活动