C++降序计数排序程序崩溃求助:vector疑似提前释放
降序计数排序崩溃原因排查
退出码134(SIGABRT)本质是内存非法访问导致堆结构损坏——你在return B;处看到的正确结果只是表象,实际内存已经被破坏,后续程序执行(比如vector的析构)触发了崩溃。结合升序版本正常,问题几乎肯定出在降序逻辑的索引处理错误,以下是核心排查点:
计数数组索引越界
升序中元素值(或偏移后的值)直接对应计数数组索引,但降序时如果直接用最大值 - 当前元素作为索引,却没保证该值落在计数数组的合法范围内(0到计数数组长度-1),就会导致越界写入,破坏堆内存。比如数组最大值是5、最小值是0,计数数组长度为6,降序索引5 - arr[i]是合法的,但如果最小值不是0却没做偏移,就可能出现负数索引。结果数组填充时的边界错误
降序填充vector B时,若循环逻辑出错(比如从B.size()而非B.size()-1开始往回写,或遍历计数数组时起始/结束位置颠倒),会写入vector内存之外的区域,破坏其内部管理结构,最终在返回后析构时触发崩溃。前缀和计算方向错误
升序计数排序的前缀和是从左到右累加,而降序需要从右到左累加计数数组。如果这一步的循环方向搞反,会导致计数数组的值异常,进而在填充结果数组时访问错误位置,引发内存破坏。
快速排查步骤
- 验证计数数组的长度:必须是
最大值 - 最小值 + 1,降序索引计算(比如max_val - arr[i] + min_val)必须落在0到数组长度-1之间。 - 检查填充B的循环:确保所有写入B的索引满足
0 <= idx < B.size(),降序遍历原数组或计数数组的逻辑要和升序严格对应反转。 - 用编译器地址 sanitizer 编译程序(添加
-fsanitize=address选项),运行后会直接定位到内存越界的具体代码行。 - 打印计数数组的所有值,对比升序版本的计数结果,确认前缀和计算逻辑正确。
内容的提问来源于stack exchange,提问作者The Developer
相关产品推荐
相关产品推荐

