C语言双指针数组移除负数函数异常求助:Case3结果不符预期
问题分析与修复
你的remove_negatives函数存在几个核心问题,导致测试用例出现异常:
1. 连续负数会被跳过
当前逻辑中,遇到负数时仅将下一个元素覆盖到当前位置,随后i直接递增。但新覆盖到当前位置的元素可能仍然是负数,比如Case3里:
i=1时处理-20,将i+1的-30移到i=1的位置i随即递增到2,跳过了对新移到i=1位置的-30的检查,导致这个负数残留
2. 数组越界访问
当i遍历到最后一个元素(i = size-1)时,访问*(*array + i +1)会超出数组内存范围,读取非法内存值,触发未定义行为(比如Case5中处理最后一个-30时的越界操作)。
3. 参数校验逻辑错误
- 判断顺序错误:先检查
!*array再检查!array,如果array本身是NULL,*array会直接触发空指针解引用崩溃,应该先判断array是否为NULL。 !**array属于无效判断:这会把第一个元素为0的数组判定为无效,但0是合法的非负数,完全不需要这个检查。
4. 元素覆盖逻辑错误
仅用下一个元素覆盖当前负数位置,没有将后续所有元素整体前移,导致出现重复元素(比如Case1里的30重复),数组有效元素没有被正确整理。
修复后的代码
采用双指针方式处理,一个指针记录有效元素的存储位置,另一个指针遍历数组,确保每个元素都被检查,同时避免越界:
short remove_negatives(long** array, const int size){ // 先检查数组指针本身,再检查指向的数组是否为空 if (!array || !*array) { printf("Error(remove_negatives): invalid array\n"); return -1; } if (size <= 0) { printf("Error(remove_negatives): invalid size\n"); return -1; } long* arr = *array; int dst = 0; // 记录有效元素的存储位置 for (int src = 0; src < size; src++) { if (arr[src] >= 0) { // 将非负数复制到有效位置,然后移动有效指针 arr[dst++] = arr[src]; } } // 返回移除的负数数量 return size - dst; }
修复逻辑说明
- 双指针遍历确保每个元素都被检查,不会遗漏连续负数;
- 没有越界访问,
src仅遍历到数组最后一个元素; - 修正了参数校验的顺序和无效判断,只保留必要的空指针与非法size检查;
- 最终数组的前
dst个元素都是非负数,调用方可通过size - 返回值得到新的有效长度。
用修复后的代码测试Case3,会得到正确结果:{10,50},移除数量为3。
内容的提问来源于stack exchange,提问作者babybrick
相关产品推荐
相关产品推荐

