动态分配的C数组意外修改致Chunk的code数组损坏
针对你取消注释代码后Chunk的code数组被损坏的情况,给你几个具体的排查方向:
检查
addValue的内存扩容逻辑
重点看addValue在给常量池扩容时,有没有错误覆盖Chunk的code数组区域。比如常量池扩容时越界写入,刚好破坏了相邻的code数组数据。可以在调用addValue(&chunk, 500)前后,打印chunk.code的前几个字节,对比是否出现异常变化。校验
writeChunk的参数合法性
你取消注释的代码里,writeChunk的第三个参数用了150,之前的调用都是123。先确认这个参数的作用:如果是行号没问题,但如果是写入长度/偏移量,150可能超出code数组的当前容量,导致越界写入。去看writeChunk的实现,检查它是否会在写入前判断剩余空间并正确扩容——要是没做扩容直接写,会覆盖Chunk结构体里的count或capacity字段,后续读取时就会误以为数组为空。检查
Chunk结构体的内存布局
arm64架构下结构体字段的对齐规则可能和其他架构不同。打印Chunk里code、constants、count等字段的内存地址,看看addValue操作常量池时,有没有因为内存越界写到code数组的头部或者count字段上。比如常量池扩容越界,刚好覆盖了code数组的起始位置,就会出现地址不变但内容被清空的情况。启用编译工具的诊断功能
在Xcode里打开Address Sanitizer(路径:Product > Scheme > Edit Scheme > Run > Diagnostics > Address Sanitizer),重新运行程序。它能直接检测出内存越界、缓冲区溢出这类问题,精准定位到出错的代码行。同时开启最高等级的编译警告(-Wall -Wextra -Werror),让编译器帮你揪出潜在的类型不匹配、参数错误等问题。逐行调试取消注释的代码
用Xcode调试器单步执行那三行代码:- 执行
location = addValue(&chunk, 500)后,检查chunk.constants的状态和chunk.code的内容是否正常; - 执行
writeChunk(&chunk, OP_CONST, 1)后,确认code数组的最后一个字节是OP_CONST; - 执行
writeChunk(&chunk, location, 150)后,立刻查看code数组的变化,看是不是这一步导致了损坏。
- 执行
内容的提问来源于stack exchange,提问作者Nicko

