调试自制Quicksort代码出现Unknown signal错误,请求排查
快速排序代码的内存错误排查
你的代码出现的两类错误,核心原因都是野指针非法访问和错误的内存释放操作,具体问题和修复方案如下:
问题分析
1. 未初始化的野指针
left和right指针在声明时没有初始化,属于野指针。第一次进入分支时:
int *tmp = left; // tmp指向随机内存地址 delete[] tmp; // 释放非法内存,触发Unknown signal
如果不执行delete[] tmp,后续复制tmp[j]时会访问野指针指向的内存,触发Segmentation fault。
2. 基准元素重复处理
循环遍历了整个数组(i < length),把基准元素n[length-1]也加入了left数组。后续合并时,原数组的基准位置会被覆盖,导致排序逻辑错误。
3. 低效且危险的动态扩容方式
每次添加元素都重新分配数组、复制旧数据、释放旧数组,不仅效率极低,还容易因指针操作失误引发内存问题。
修复后的代码
#include <iostream> #include <cmath> using namespace std; void quicksort(int *n, int length) { if (length > 1) { int pivot = n[length - 1]; int leftLength = 0, rightLength = 0; // 先统计左右分区的元素数量 for (int i = 0; i < length - 1; i++) { if (n[i] <= pivot) { leftLength++; } else { rightLength++; } } // 一次性分配内存,避免反复扩容 int *left = new int[leftLength]; int *right = new int[rightLength]; int lIdx = 0, rIdx = 0; // 填充左右分区 for (int i = 0; i < length - 1; i++) { if (n[i] <= pivot) { left[lIdx++] = n[i]; } else { right[rIdx++] = n[i]; } } // 递归排序 if (leftLength > 1) quicksort(left, leftLength); if (rightLength > 1) quicksort(right, rightLength); // 合并结果:左分区 + 基准元素 + 右分区 for (int i = 0; i < leftLength; i++) { n[i] = left[i]; } n[leftLength] = pivot; for (int i = 0; i < rightLength; i++) { n[leftLength + 1 + i] = right[i]; } // 释放内存 delete[] left; delete[] right; } } int main() { // 测试示例 int arr[] = {3, 1, 4, 1, 5, 9, 2, 6}; int len = sizeof(arr) / sizeof(arr[0]); quicksort(arr, len); for (int num : arr) { cout << num << " "; } return 0; }
关键修改点
- 先统计左右分区长度,一次性分配内存,避免反复动态扩容的指针操作
- 初始化
left和right为合法分配的内存,彻底解决野指针问题 - 跳过基准元素的遍历,最后单独将基准元素插入到合并后的正确位置
- 合并逻辑修正,确保基准元素处于左右分区的中间
内容的提问来源于stack exchange,提问作者Phạm Thiên Minh
相关产品推荐
相关产品推荐

