Skip to content

Commit 1f18486

Browse files
committed
Minor fixes
1 parent 10c25cf commit 1f18486

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

tutorial05_answer/tutorial05_answer.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,14 +178,14 @@ static int lept_parse_array(lept_context* c, lept_value* v) {
178178
}
179179
~~~
180180
181-
然后,我们把这个指针调用 `lept_parse_value(c, e)`,这里会出现问题,因为 `lept_parse_value()` 及之下的函数都需要调用 `lept_context_push()`,而 `lept_context_push()` 在发现栈满了的时候会用 `realloc()` 堆栈。这时候,我们上层的 `e` 就会失效,变成一个悬挂指针(dangling pointer),而且 `lept_parse_value(c, e)` 会通过这个指针写入解析结果,造成非法访问。
181+
然后,我们把这个指针调用 `lept_parse_value(c, e)`,这里会出现问题,因为 `lept_parse_value()` 及之下的函数都需要调用 `lept_context_push()`,而 `lept_context_push()` 在发现栈满了的时候会用 `realloc()` 扩容。这时候,我们上层的 `e` 就会失效,变成一个悬挂指针(dangling pointer),而且 `lept_parse_value(c, e)` 会通过这个指针写入解析结果,造成非法访问。
182182
183183
在使用 C++ 容器时,也会遇到类似的问题。从容器中取得的迭代器(iterator)后,如果改动容器内容,之前的迭代器会失效。这里的悬挂指针问题也是相同的。
184184
185185
但这种 bug 有时可能在简单测试中不能自动发现,因为问题只有堆栈满了才会出现。从测试的角度看,我们需要一些压力测试(stress test),测试更大更复杂的数据。但从编程的角度看,我们要谨慎考虑变量的生命周期,尽量从编程阶段避免出现问题。例如把 `lept_context_push()` 的 API 改为:
186186
187187
~~~
188-
static void lept_context_push(lept_context* c, void* data, size_t size);
188+
static void lept_context_push(lept_context* c, const void* data, size_t size);
189189
~~~
190190
191191
这样就确把数据压入栈内,避免了返回指针的生命周期问题。但我们之后会发现,原来的 API 设计在一些情况会更方便一些,例如在把字符串值转化(stringify)为 JSON 时,我们可以预先在堆栈分配字符串所需的最大空间,而当时是未有数据填充进去的。

0 commit comments

Comments
 (0)