GDB中出现Cannot access memory at address错误的快速排序问题排查
问题原因分析
段错误的核心原因是数组访问越界,具体出在partition函数的两个do-while循环中:
- 第一个循环:
do {i++;} while (arr[i] <= pivot);当数组中存在多个等于pivot的元素,或者pivot是当前子数组的最大值时,i会持续递增,直到超出数组的合法索引范围,访问到不属于数组的内存区域。 - 第二个循环:
do {j--;} while (arr[j] > pivot);同理,若pivot是当前子数组的最小值,j会持续递减到负数索引,同样触发越界访问。
修复方案
针对Hoare分区算法的正确逻辑调整循环条件,同时确保循环不会超出数组的low和high边界:
修正后的partition函数
/* This function returns the pivot position, initially the pivot is set to the first element */ int partition(int arr[], int low, int high) { int pivot = arr[low]; int i = low - 1; int j = high + 1; while (1) { /* 使用1代替自定义的true,避免宏定义冲突 */ // 找到第一个大于pivot的元素,同时确保i不超过high do { i++; } while (i <= high && arr[i] <= pivot); // 找到第一个小于等于pivot的元素,同时确保j不小于low do { j--; } while (j >= low && arr[j] > pivot); if (i >= j) /* 当索引交叉时返回j */ return j; swap(&arr[i], &arr[j]); } }
额外优化(提升输出体验)
print_array函数末尾添加换行,避免输出内容混乱:
void print_array(int arr[], int size) { printf("The array for quick sort algorithm\n"); for (int i = 0; i < size; i++) { printf("%d\t", arr[i]); } printf("\n"); // 添加换行 }
修复原理
- 在两个do-while循环中分别加入
i <= high和j >= low的边界检查,确保索引不会超出当前子数组的合法范围,从根源避免内存越界。 - 把自定义的
true宏替换为1,避免和标准库中可能存在的true定义冲突(属于代码规范优化)。
内容的提问来源于stack exchange,提问作者skm
相关产品推荐
相关产品推荐

