C++中delete[]释放lsh_distances二维数组报free(): invalid size错误
问题根因
你遇到的free(): invalid size报错和析构函数的释放逻辑无关,本质是lsh_distances数组发生了越界写入,破坏了堆内存的元数据,导致释放时系统无法识别合法的内存块大小。
你贴的valgrind日志已经明确指出了问题点:
- 越界写入发生在
neighbour_search.cpp第66行,也就是lsh_distances[i][p2->pos] = used_distance(*p1, *p2);这行代码 - 写入的地址比你申请到的内存块起始地址还要早8/16字节,这部分是堆分配器用来存储内存块大小、校验信息的元数据区域,被改写后
free操作读取到非法的块大小就会直接崩溃。
排查和修复方案
你的初步怀疑方向是对的,直接按以下步骤验证即可:
- 在赋值
lsh_distances[i][p2->pos]前,添加范围校验逻辑,确认p2->pos的取值合法:
const Point *p2 = buckets[j]->points[k]; // 校验pos取值必须在申请的数组下标范围内 assert(p2->pos >= 0 && static_cast<unsigned int>(p2->pos) < ind_size); lsh_distances[i][p2->pos] = used_distance(*p1, *p2);
- 大概率会命中断言:
p2->pos为负数,或者大于等于你申请数组时用的index_dataset.points.size()值,你这的报错是写入位置在内存块之前,更倾向于p2->pos为负数的情况。 - 进一步排查
Point结构体的pos字段初始化逻辑,确认是否存在未初始化、其他地方误修改的问题即可。
修复越界写入问题后,原有析构函数的释放逻辑可以正常运行,不会再报错,也不会出现内存泄漏。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

