记录cJSON_AddItemToArray使用的一个小坑

记录cJSON_AddItemToArray使用的一个小坑

话不多说,上代码(示例)。

.... 
//以下代码示例组装一个json数组结点destarray
cJSON *destarray = nullptr;
destarray = cJSON_CreateArray(); //创建一个空的json目标数组结点
cJSON *dbarray = nullptr;
dbarray = DBgetxxx(); //从其它地方获取的json数组,比如通过 sqlite 库中db_query_sql_json_new接口从数据库获取的
if (dbarray != nullptr)
{
    int size = cJSON_GetArraySize(dbarray);
    for (int i = 0; i < size; i++)
    {
        cJSON * arrayItem = cJSON_GetArrayItem(dbarray, i); //从dbarray取出子json 
        if (arrayItem != nullptr) {
            cJSON_AddItemToArray(destarray, arrayItem); //将子json添加到目标array中
        }
    }
....
}
....//继续添加其它json数据到destarray结点

嗯看着似乎没啥问题,但是实际调试的时候却发现,只有dbarray中的第一个子json成功地添加到了destarray中,后面的子json都没添加成功,如果添加调试就会发现,这些没添加成功的arrayItem 是nullptr
检查一下cJSON中cJSON_GetArrayItem 和 cJSON_AddItemToArray的源码:

static cJSON* get_array_item(const cJSON *array, size_t index)
{
    cJSON *current_child = NULL;

    if (array == NULL)
    {
        return NULL;
    }

    current_child = array->child;
    while ((current_child != NULL) && (index > 0))
    {
        index--;
        current_child = current_child->next;
    }

    return current_child;
}

static cJSON_bool add_item_to_array(cJSON *array, cJSON *item)
{
    cJSON *child = NULL;

    if ((item == NULL) || (array == NULL) || (array == item))
    {
        return false;
    }

    child = array->child;
    /*
     * To find the last item in array quickly, we use prev in array
     */
    if (child == NULL)
    {
        /* list is empty, start new one */
        array->child = item;
        item->prev = item;
        item->next = NULL;
    }
    else
    {
        /* append to the end */
        if (child->prev)
        {
            suffix_object(child->prev, item);
            array->child->prev = item;
        }
    }

    return true;
}

问题就出在add_item_to_array中当array->child == NULL的时候,会将item->next置为NULL,说白了就是在本例中,当目标json数组destarray是空的时候,第一次调用cJSON_AddItemToArray(destarray,arrayItem);的时候,会将arrayItem的next指针置为空。而arrayItem是dbarray的一个child,arrayItem->next就是dbarray的下一个child,这可不就导致出问题了。
知道了原因那就好办了,解决方法示例:

...
if (dbarray != nullptr)
{
    int size = cJSON_GetArraySize(dbarray);
    cJSON *arrayItem [size] = {0};
    for (int i = 0; i < size; i++)
    {
        cJSON * arrayItem[i] = cJSON_GetArrayItem(dbarray, i); //从dbarray取出子json,先用数组存起来,存完再统一添加到destarray
    }
    for (int j = 0; j < size; j++)
    {
        if (arrayItem[j] != nullptr)
        {
            cJSON_AddItemToArray(destarray,arrayItem[j]); 
        }
    }
}
....

总之,使用cJSON_AddItemToArray的时候小心一点就是了~

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值