cJSON的一个小坑:有归属的json对象itemA调用cJSON_AddItemToObject添加到其他对象中,会带入itemA的next对象。

对于对cJSON不太熟的同学来说,容易踩到这个坑。特记录一下。
小坑现象:有归属的json对象itemA调用cJSON_AddItemToObject添加到其他对象中,会带入itemA的next对象。
比如有一个带有itemA的json对象root_a如下:

{
    "f_name":"f_value",
    "itemA":{
        "nameA":"valueA"
    },
    "l_name":"l_value"
}

现在有个需求,需要将itemA的内容取出来添加到另外应该json对象root_b中。
获取itemA的函数:

cJSON *itemA;
itemA=cJSON_GetObjectItem(root_a,"itemA");

root_b如下:

{
"name1":"value1",
"name2":"value2"
}

想通过调用cJSON_AddItemToObject达到的目标效果如下:
即执行:

cJSON_AddItemToObject(root_b,"itemA",itemA);

期望的结果:

{
    "name1":"value1",
    "name2":"value2",
    "itemA":{
        "nameA":"valueA"
    }
}

但执行以下的函数调用后的实际结果如下:

{
"name1":"value1",
"name2":"value2",
"itemA":{
        "nameA":"valueA"
    },
 "l_name":"l_value"
}

可以看到函数将后面的对象l_name也一起加入到了root_b中。不知道这个是cJSON的bug还是就是这样设计的,根据cJSON的结构体来分析,cJSON_AddItemToObject将itemA对象的next的值也加入到了root_b中。

正确的方法:
在这种情况下,采用cJSON_AddItemReferenceToObject来实现,不要用cJSON_AddItemToObject函数。
itemA的内存释放不归属于root_b,而是归属于root_a。
即执行:

cJSON_AddItemReferenceToObject(root_b,"itemA",itemA);

就能得到正确的结果。

两个函数的区别说明如下:
/向对象中添加键值对,值的类型与相关函数有关/
extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);

/* 将对象的引用附加到指定的数组/对象。当您想要将现有的cJSON添加到新的cJSON中,但又不想破坏现有的cJSON时,请使用此选项 */
extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);

附:cJSON结构体:


/* The cJSON structure: */
typedef struct cJSON
{
    /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
    struct cJSON *next;
    struct cJSON *prev;
    /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
    struct cJSON *child;

    /* The type of the item, as above. */
    int type;

    /* The item's string, if type==cJSON_String  and type == cJSON_Raw */
    char *valuestring;
    /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
    int valueint;
    /* The item's number, if type==cJSON_Number */
    double valuedouble;

    /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
    char *string;
} cJSON;
  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值