使用指针合并两个有序数组出现垃圾值,求问题原因排查
指针法合并有序数组出现垃圾值的问题排查
问题描述
尝试用指针法合并两个有序数组,合并后的arr3前6个元素正常,但后续出现垃圾值,代码如下:
#include<iostream> using namespace std; int main() { int arr1[] = { 1,3,4,6 }; int arr2[] = { 2,3,4,5 }; int n1 = 4; int n2 = 4; int arr3[10]; int* endptr = &arr1[0]; int* endptr2 = &arr2[0]; int* endptr3 = arr3; int k = 0; while (endptr < &arr1[n1-1] && endptr2 < &arr2[n2-1]) { if (endptr[0] < endptr2[0]) { endptr3[k++] = endptr[0]; endptr++; } else { endptr3[k++] = endptr2[0]; endptr2++; } } while (endptr < &arr1[n1 - 1]) { endptr3[k++] = endptr[0]; endptr++; } while (endptr2 < &arr2[n2 - 1]) { endptr3[k++] = endptr[0]; endptr2++; } cout << arr3[5]; }
错误分析与修复
问题源于指针循环条件错误+代码笔误,具体三个关键点:
循环条件遗漏最后一个元素
原代码用endptr < &arr1[n1-1]作为循环终止条件,这会让指针在到达数组最后一个元素时停止(最后一个元素的地址就是&arr1[n1-1],<不满足),导致两个数组的最后一个元素都没被合并。
修复:将循环条件改为endptr < arr1 + n1(C++推荐的尾后指针写法,更直观),或者endptr <= &arr1[n1-1]。最后一个循环的笔误
第三个while循环中,错误地将endptr2[0]写成了endptr[0],此时endptr已经走到arr1的末尾(甚至越界),赋值的是垃圾内存的值。
修复:把endptr[0]替换为endptr2[0]。(可选优化)指针直接取值更简洁
既然用了指针,直接通过*endptr访问元素即可,无需endptr[0],代码可读性更强。
修复后的完整代码
#include<iostream> using namespace std; int main() { int arr1[] = { 1,3,4,6 }; int arr2[] = { 2,3,4,5 }; int n1 = sizeof(arr1)/sizeof(arr1[0]); // 自动计算数组长度更可靠 int n2 = sizeof(arr2)/sizeof(arr2[0]); int arr3[10]; int* ptr1 = arr1; // 数组名直接作为指针,等价于&arr1[0] int* ptr2 = arr2; int* ptr3 = arr3; int k = 0; // 合并两个数组的共同遍历部分 while (ptr1 < arr1 + n1 && ptr2 < arr2 + n2) { if (*ptr1 < *ptr2) { ptr3[k++] = *ptr1++; // 先取值再自增,简化写法 } else { ptr3[k++] = *ptr2++; } } // 处理arr1剩余元素 while (ptr1 < arr1 + n1) { ptr3[k++] = *ptr1++; } // 处理arr2剩余元素 while (ptr2 < arr2 + n2) { ptr3[k++] = *ptr2++; } // 打印全部合并结果验证 for (int i = 0; i < k; i++) { cout << arr3[i] << " "; } cout << endl; return 0; }
验证结果
修复后运行输出:1 2 3 3 4 4 5 6,所有元素均为有效合并值,无垃圾值。
内容的提问来源于stack exchange,提问作者Muhammad Abdullah BSCS 2022 FA
相关产品推荐
相关产品推荐

