json的基础介绍
JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范) 的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。json常用于对象的序列化,和反序列化。
cJSON的核心实现机制
在C环境中使用json需要导入 cjson库,简单介绍一下其内部的工作原理。
在cJSON库中,最重要的两块分别为JSON解析和JSON节点的增删改查。
使用树结构存储JSON的各个节点。而这个JSON树是使用双向链表实现的。例如
{
"name": "Jack (\"Bee\") Nimble",
"format": {
"type": "rect",
"width": 1920,
"height": 1080,
"interlace": false,
"frame rate": 24
}
双向链表的每一个节点都是cJSON指针。一个完整的双向链表表示一连串兄弟节点。在示例JSON中,name和format节点组合成一个 链表,type,width,height,interlace和frame rate节点组成一个链表。
JSON树的每一层都是一个双向链表,表示一堆兄弟节点。当前层的所有节点都是当前链表头节点的父节点的子节点。在示例JSON 中,type,width,height,interlace和frame rate节点都是format节点的子节点。实线表示节点间有真实的引用关系,而虚线表示 逻辑上的引用关系。
JSON正反词法分析,具体的词法分析流程不做介绍
正向词法分析:将字符串文本(char *)转换为JSON树。
反向词法分析:将JSON树转换为可存储打印的字符串文本(char *)。
cJSON的内存管理
cJSON库提供了钩子函数来帮助用户自定义内存管理函数,如果不设置,这默认为malloc和free。
自动模式下的内存管理
在自动模式下,cJSON使用默认的malloc和free函数管理内存。
在cJSON中,每个节点都是malloc而来,每个节点的string和valuestring也是malloc而来。
使用cJSON库中,使用cJSON_Delete函数可以递归释放JSON树中malloc的节点内存和字符内存。
当使用cJSON_Print函数后,需要手动释放cJSON_Print函数分配的内存,避免内存泄露。
手动模式下的内存管理
在手动模式下,需要指定钩子cJSON_Hooks的指向。cJSON_Hooks结构如下:
typedef struct cJSON_Hooks
{
void *(*malloc_fn)(size_t sz);
void (*free_fn)(void *ptr);
} cJSON_Hooks;
只要通过cJSON_Hooks指定了内存分配和释放的函数,在之后的使用中将自动使用指定的函数进行内存分配和释放。
假设已经有了一个自定义的内存分配函数my_malloc, 内存释放函数my_free。使用如下:
cJSON_InitHooks *hooks = NULL;
hooks = (cJSON_InitHooks *)calloc(1, sizeof(cJSON_InitHooks));
hooks