释放LinesArray时程序无法正常退出的问题排查
看起来你在实现Crafting Interpreters的行号游程编码时踩了内存操作的坑,程序在调用freeLines时卡住,这大概率是因为之前的数组操作出现了内存越界,破坏了堆的结构,导致后续释放内存时出现异常。咱们一步步拆解问题:
核心问题:数组索引与count变量管理完全混乱
你的设计思路是用[行号, 计数, 行号, 计数,...]的格式存储游程编码,但代码里对count的处理混淆了「已存储元素总数」和「最后一个元素的索引」的概念,直接引发了内存越界:
初始化阶段的索引错位
if(array->count == 0){ array->lines[array->count] = line; // lines[0] = line array->count++; // count 变为 1 array->lines[array->count] = 1; // lines[1] = 1,但count没增加到2 }这里明明写入了两个元素,但
count只标记为1,后续所有基于count的判断、索引都会彻底错位。扩容逻辑判断不足
当需要添加新的行号条目时,需要占用2个数组位置(行号+计数),但你的扩容判断只检查了capacity < array->count + 1,这会导致需要写入两个元素时,内存空间不够却没有扩容,直接触发数组越界。新行号添加时的
count操作错误
遇到新行号时,你两次自增count再写入数据:array->count++; array->lines[array->count] = line; array->count++; array->lines[array->count] = 1;比如
count初始是1,执行后count变成3,此时count表示的是最后一个元素的索引,而非已用元素总数,这会让后续的数组访问完全偏离预期,进一步破坏内存。内存越界的连锁反应
上述错误会让你访问超出malloc分配的内存区域,破坏堆的元数据。堆结构损坏后,后续调用free(也就是FREE_ARRAY宏)时,系统无法正确解析堆内存,就会出现程序卡住、崩溃等异常。
修复后的代码示例
咱们重新定义count的含义:让count表示数组中已使用的元素总数,每个游程条目固定占2个元素(行号+计数),这样所有操作都会清晰可控:
#include "lines.h" #include "memory.h" void writeLines(LinesArray* array, Line line) { // 要添加新条目需要2个位置,提前检查扩容 if (array->capacity < array->count + 2) { int oldCapacity = array->capacity; array->capacity = GROW_CAPACITY(oldCapacity); array->lines = GROW_ARRAY(Line, array->lines, oldCapacity, array->capacity); } if (array->count == 0) { // 第一个条目:行号在索引0,计数在索引1 array->lines[0] = line; array->lines[1] = 1; array->count = 2; // 明确标记已使用2个元素 } else { // 最后一个行号的索引是 count-2,计数是 count-1 Line lastLine = array->lines[array->count - 2]; if (lastLine == line) { // 计数加1 array->lines[array->count - 1]++; } else { // 写入新行号和计数,更新已用元素数 array->lines[array->count] = line; array->lines[array->count + 1] = 1; array->count += 2; } } } void freeLines(LinesArray* array) { FREE_ARRAY(Line, array->lines, array->capacity); initLines(array); }
额外的小细节
你的lines.c里头文件引用少了闭合双引号:
#include "lines.h // 修正为 #include "lines.h" #include "memory.h // 修正为 #include "memory.h"
这个语法错误会导致编译失败,记得一起改了。
修复这些问题后,数组的内存操作就符合堆的管理规则了,freeLines能正常执行,程序也不会再卡住啦。
备注:内容来源于stack exchange,提问作者user22873067

