std::make_unique<bool[]>报malloc无效大小错误与内存越界问题排查
问题排查结果
1. std::make_unique<bool[]>调用失败原因
malloc(): invalid size (unsorted) 错误本质是堆内存元数据被提前破坏,并非make_unique本身的问题:
- 你的
operator+重载存在明确的内存越界问题,小数据量(5000位乘法)下堆破坏的影响未触发malloc校验,大数据量(13000位乘法)下内存分配/释放次数大幅提升,被破坏的堆元数据刚好在make_unique调用时被检测到,直接触发崩溃。 - 额外检查点:
- 校验子数组构造函数的
start入参范围,确保start + dimensions_ <= ref.dimensions_,避免memcpy越界读进一步破坏堆。 - 确认
ref.dimensions_不会为0:dimensions_是无符号类型,如果ref.dimensions_ == 0,ref.dimensions_-1会溢出为无符号数最大值,导致make_unique尝试分配超大内存直接失败。
- 校验子数组构造函数的
2. operator+内存越界根因
完全匹配valgrind的报错特征,核心问题是数组下标使用错误,将数组长度直接作为索引访问:
以你的测试用例为例:
m1/m2的size() == 2,数组有效索引范围是0~1,你直接用y[max](max = y.size() =2)访问,刚好触发0 bytes after a block of size 2 alloc'd的越界读。- 构造返回数组
ret时++mSize =3,ret的有效索引范围是0~2,你直接用ret[mSize](mSize=3)写入,刚好触发0 bytes after a block of size 3 alloc'd的越界写。
修复方案
调整operator+的索引初始化逻辑即可:
friend BoolArray operator+(BoolArray &x, BoolArray &y) { if (x.size() <= y.size()) { // 索引初始值为长度-1,对应最后一个有效元素 int max_idx = y.size() - 1; int min_idx = x.size() - 1; int ret_len = y.size() + 1; auto ret = BoolArray(ret_len); int ret_idx = ret_len -1; bool remainder = 0; for (; min_idx >= 0; --min_idx) { ret[ret_idx] = output_[remainder][ y[max_idx] ][x[min_idx] ]; remainder = carry_[remainder][ y[max_idx] ][ x[min_idx] ]; --max_idx; --ret_idx; } for (; max_idx >= 0; --max_idx) { ret[ret_idx] = output_[remainder][ y[max_idx] ][ 0 ]; remainder = carry_[remainder][ y[max_idx] ][ 0 ]; --ret_idx; } if (remainder) { ret[ret_idx] = 1; return ret; } else { auto newRet = BoolArray(ret,1); return newRet; } }
内容的提问来源于stack exchange,提问作者Steveit
相关产品推荐
相关产品推荐

