json-c官方API文档
int index = 0;
char buff[1024] = {0};
index += sprintf(buff + index, "{rn");
index += sprintf(buff + index, ""serial_para":rn");
index += sprintf(buff + index, "[rn");
index += sprintf(buff + index, "{rn");
index += sprintf(buff + index, ""device_name":"_/dev/ttyS3",rn");
index += sprintf(buff + index, ""ip_addr":"10.20.1.83",rn");
index += sprintf(buff + index, ""ip_port":9333,rn");
index += sprintf(buff + index, ""speed":115200,rn");
index += sprintf(buff + index, ""data_bit":8,rn");
index += sprintf(buff + index, ""stop_bit":1,rn");
index += sprintf(buff + index, ""parity":"N"rn");
index += sprintf(buff + index, "},rn");
index += sprintf(buff + index, "{rn");
index += sprintf(buff + index, ""device_name":"_/dev/ttyS5",rn");
index += sprintf(buff + index, ""ip_addr":"10.20.1.83",rn");
index += sprintf(buff + index, ""ip_port":9555,rn");
index += sprintf(buff + index, ""speed":115200,rn");
index += sprintf(buff + index, ""data_bit":8,rn");
index += sprintf(buff + index, ""stop_bit":1,rn");
index += sprintf(buff + index, ""parity":"N"rn");
index += sprintf(buff + index, "}rn");
index += sprintf(buff + index, "]rn");
index += sprintf(buff + index, "}rn");
//以上代码段生成JSON格式的buff如下
{
serial_para:
[
{
"device_name":"_/dev/ttyS3",
"ip_addr":"10.20.1.83",
"ip_port":9333,
"speed":115200,
"data_bit":8,
"stop_bit":1,
"parity":"N"
},
{
"device_name":"_/dev/ttyS5",
"ip_addr":"10.20.1.83",
"ip_port":9335,
"speed":115200,
"data_bit":8,
"stop_bit":1,
"parity":"N"
}
]
}
解析JSON格式
struct serial_para {
char dev_name[16];
char ip_addr[16];
int ip_port;
int speed;
int databit;
int stopbit;
char parity[32];
};
int handle_json_data(char *buff) {
int i = 0;
int ret = 0;
size_t array_cnt;
char tmp[32] = {0};
char msg[128] = {0};
json_object *obj, *sub_obj;
struct serial_para serial_info;
//serial_info = (struct serial_para *)malloc(sizeof(struct serial_para));
obj = sub_obj = NULL;
const char *ok_msg = {"{"status":"OK"}"};
const char *err_msg1 = {"{"status":"Invalid JSON Format"}"};
const char *err_msg2 = {"{"status":"Invalid param"}"};
obj = json_tokener_parse(buff);
if (obj == NULL) {
strcpy(msg, err_msg1);
log_info("client data Invalid JSON Format");
return -1;
}
ret = json_object_object_get_ex(obj, "serial_para", &sub_obj);
if (ret != 1) {
log_info("Fails to get params");
strcpy(msg, err_msg2);
return -1;
}
enum json_type type = json_object_get_type(sub_obj);
if(type == json_type_array) {
array_cnt = json_object_array_length(sub_obj);
log_info("get json array success cnt = %d", array_cnt);
for(i = 0; i < array_cnt; i++) {
json_object *array_obj = json_object_array_get_idx(sub_obj, i);
get_json_string(array_obj, "device_name", tmp);
strcpy(serial_info.dev_name, tmp);
memset(tmp, 0, 32);
get_json_string(array_obj, "ip_addr", tmp);
strcpy(serial_info.ip_addr, tmp);
memset(tmp, 0, 32);
get_json_string(array_obj, "ip_port", tmp);
serial_info.ip_port = atoi(tmp);
memset(tmp, 0, 32);
get_json_string(array_obj, "speed", tmp);
serial_info.speed = atoi(tmp);
memset(tmp, 0, 32);
get_json_string(array_obj, "data_bit", tmp);
serial_info.databit = atoi(tmp);
memset(tmp, 0, 32);
get_json_string(array_obj, "stop_bit", tmp);
serial_info.stopbit = atoi(tmp);
memset(tmp, 0, 32);
get_json_string(array_obj, "parity", tmp);
strcpy(serial_info.parity, tmp);
memset(tmp, 0, 32);
sys_serial2net(serial_info);
memcpy(&serial_info_g[i], &serial_info, sizeof(struct serial_para));
if (array_obj != NULL) {
//json_object_put(array_obj);
}
}
}
if (obj != NULL) {
//json_object_put(obj);
}
if (sub_obj != NULL) {
//json_object_put(sub_obj);
}
strcpy(msg, ok_msg);
return 0;
}
其中json_object_put全部注释掉了,因为发现任何一个json_object_put都会导致段错误,查看API文档后发现json_object_array_get_idx函数会释放这些变量的空间,当再次释放的时候就会导致double free的段错误。以下是官网API表述。
JSON_EXPORT int json_object_put ( 结构json_object * 对象 )
减少 json_object 的引用计数,如果达到零则释放。
在执行此操作之前,您必须拥有 obj 的所有权,否则会导致引用计数不平衡,从而导致经典的 use-after-free 错误。特别是,您通常不需要调用orjson_object_put()返回的 json_object 。json_object_object_get() 、json_object_array_get_idx()
就像在调用一块内存之后一样,在调用它或它所属的任何对象之后free(),你不能使用它(除非你知道你已经调用了显式增加引用计数)。objjson_object_put()json_object_get(obj)
NULL 可能会被传递,这种情况下这是一个空操作。



