JSON

从零开始的JSON库教程(五):解析数组解答篇

字号+ 作者:H5之家 来源:H5之家 2016-10-20 14:00 我要评论( )

本文是《从零开始的 JSON 库教程》的第五个单元解答篇。解答代码位于json-tutorial/tutorial05_answer。 1. 编写 test_parse_array() 单元测试 这个练习纯粹为了

> 脚本语言 > >

从零开始的JSON库教程(五):解析数组解答篇 2016-10-14 11:25 出处:清屏网 人气: 

本文是 《从零开始的 JSON 库教程》 的第五个单元解答篇。解答代码位于 json-tutorial/tutorial05_answer 。

1. 编写 test_parse_array() 单元测试

这个练习纯粹为了熟习数组的访问 API。新增的第一个 JSON 只需平凡的检测。第二个 JSON 有特定模式,第 i 个子数组的长度为 i,每个子数组的第 j 个元素是数字值 j,所以可用两层 for 循环测试。

static void test_parse_array() { size_t i, j; lept_value v; /* ... */ lept_init(&v); EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(&v, "[ null , false , true , 123 , \"abc\" ]")); EXPECT_EQ_INT(LEPT_ARRAY, lept_get_type(&v)); EXPECT_EQ_SIZE_T(5, lept_get_array_size(&v)); EXPECT_EQ_INT(LEPT_NULL, lept_get_type(lept_get_array_element(&v, 0))); EXPECT_EQ_INT(LEPT_FALSE, lept_get_type(lept_get_array_element(&v, 1))); EXPECT_EQ_INT(LEPT_TRUE, lept_get_type(lept_get_array_element(&v, 2))); EXPECT_EQ_INT(LEPT_NUMBER, lept_get_type(lept_get_array_element(&v, 3))); EXPECT_EQ_INT(LEPT_STRING, lept_get_type(lept_get_array_element(&v, 4))); EXPECT_EQ_DOUBLE(123.0, lept_get_number(lept_get_array_element(&v, 3))); EXPECT_EQ_STRING("abc", lept_get_string(lept_get_array_element(&v, 4)), lept_get_string_length(lept_get_array_element(&v, 4))); lept_free(&v); lept_init(&v); EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(&v, "[ [ ] , [ 0 ] , [ 0 , 1 ] , [ 0 , 1 , 2 ] ]")); EXPECT_EQ_INT(LEPT_ARRAY, lept_get_type(&v)); EXPECT_EQ_SIZE_T(4, lept_get_array_size(&v)); for (i = 0; i < 4; i++) { lept_value* a = lept_get_array_element(&v, i); EXPECT_EQ_INT(LEPT_ARRAY, lept_get_type(a)); EXPECT_EQ_SIZE_T(i, lept_get_array_size(a)); for (j = 0; j < i; j++) { lept_value* e = lept_get_array_element(a, j); EXPECT_EQ_INT(LEPT_NUMBER, lept_get_type(e)); EXPECT_EQ_DOUBLE((double)j, lept_get_number(e)); } } lept_free(&v); } 2. 解析空白字符

按现时的 lept_parse_array() 的编写方式,需要加入 3 个 lept_parse_whitespace() 调用,分别是解析 [ 之后,元素之后,以及 , 之后:

static int lept_parse_array(lept_context* c, lept_value* v) { /* ... */ EXPECT(c, '['); lept_parse_whitespace(c); /* ... */ for (;;) { /* ... */ if ((ret = lept_parse_value(c, &e)) != LEPT_PARSE_OK) return ret; /* ... */ lept_parse_whitespace(c); if (*c->json == ',') { c->json++; lept_parse_whitespace(c); } /* ... */ } } 3. 内存泄漏

成功测试那 3 个 JSON 后,使用内存泄漏检测工具会发现 lept_parse_array() 用 malloc()分配的内存没有被释放:

==154== 124 (120 direct, 4 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 4 ==154== at 0x4C28C20: malloc (vg_replace_malloc.c:296) ==154== by 0x409D82: lept_parse_array (in /json-tutorial/tutorial05/build/leptjson_test) ==154== by 0x409E91: lept_parse_value (in /json-tutorial/tutorial05/build/leptjson_test) ==154== by 0x409F14: lept_parse (in /json-tutorial/tutorial05/build/leptjson_test) ==154== by 0x405261: test_parse_array (in /json-tutorial/tutorial05/build/leptjson_test) ==154== by 0x408C72: test_parse (in /json-tutorial/tutorial05/build/leptjson_test) ==154== by 0x40916A: main (in /json-tutorial/tutorial05/build/leptjson_test) ==154== ==154== 240 (96 direct, 144 indirect) bytes in 1 blocks are definitely lost in loss record 4 of 4 ==154== at 0x4C28C20: malloc (vg_replace_malloc.c:296) ==154== by 0x409D82: lept_parse_array (in /json-tutorial/tutorial05/build/leptjson_test) ==154== by 0x409E91: lept_parse_value (in /json-tutorial/tutorial05/build/leptjson_test) ==154== by 0x409F14: lept_parse (in /json-tutorial/tutorial05/build/leptjson_test) ==154== by 0x40582C: test_parse_array (in /json-tutorial/tutorial05/build/leptjson_test) ==154== by 0x408C72: test_parse (in /json-tutorial/tutorial05/build/leptjson_test) ==154== by 0x40916A: main (in /json-tutorial/tutorial05/build/leptjson_test)

很明显,有 malloc() 就要有对应的 free()。正确的释放位置应该放置在 lept_free(),当值被释放时,该值拥有的内存也在那里释放。之前字符串的释放也是放在这里:

void lept_free(lept_value* v) { assert(v != NULL); if (v->type == LEPT_STRING) free(v->u.s.s); v->type = LEPT_NULL; }

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • JSON解析和XML解析对比,JSON解析XML解析

    JSON解析和XML解析对比,JSON解析XML解析

    2016-10-21 11:01

  • 使用Couchbase存储Non-JSON数据

    使用Couchbase存储Non-JSON数据

    2016-10-18 16:01

  • 利用Ajax和JSON技术实现对数据库的异步操作

    利用Ajax和JSON技术实现对数据库的异步操作

    2016-10-18 15:00

  • Json .NET操作

    Json .NET操作

    2016-10-18 14:00

网友点评
b