You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

修复逻辑说明

  1. 双指针遍历确保每个元素都被检查,不会遗漏连续负数;
  2. 没有越界访问,src仅遍历到数组最后一个元素;
  3. 修正了参数校验的顺序和无效判断,只保留必要的空指针与非法size检查;
  4. 最终数组的前dst个元素都是非负数,调用方可通过size - 返回值得到新的有效长度。

用修复后的代码测试Case3,会得到正确结果:{10,50},移除数量为3。

内容的提问来源于stack exchange,提问作者babybrick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 18:24:29