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

C语言按指定值拆分数组时循环外访问数组异常问题排查

代码错误说明

你的问题和数组作用域没有关系,代码一共存在3个核心语法/逻辑错误:

  • 零长度数组越界访问
    你声明的int iList_2small[] = {};、int iList_3large[] = {};属于零长度数组,编译时给这俩数组分配的空间大小为0,没有预留存储元素的内存位置。你后续往数组下标位置赋值属于越界访问未分配内存,是C语言标准定义的未定义行为:
    • 用sizeof(iList_2small)算出来长度为0是正常结果,因为数组本身声明的大小就是0,sizeof是编译阶段就确定的值,不会因为你往内存里写了数据就改变
    • 你能通过iList_2small[10]读到56,纯粹是越界后刚好读到了原数组iList_1在栈上的相邻内存数据,不是这个数组真的存储了对应元素
  • 计数器变量作用域错误
    你把记录小数组写入位置的step_L2、step_L3定义在了for循环内部,每次循环迭代时这两个变量都会被重新初始化为0,导致每次写入都只覆盖下标0的位置,根本无法累计存储多个元素。
  • 数组长度计算逻辑错误
    C语言原生数组是固定长度的静态结构(除非手动调用malloc实现动态扩容),不会像Python列表一样随着元素插入自动增长长度,sizeof计算的是数组声明时占用的总内存大小,不会统计你越界写入的元素数量,因此不能用这种方式计算拆分后数组的实际元素个数。
修正方案
  1. 给两个拆分后的数组预分配足够的空间:因为拆分后元素总数最多和原数组相等,直接开和原数组等长的空间即可
  2. 把写入位置计数器挪到for循环外初始化,避免每次循环被重置
  3. 拆分完成后,直接用计数器的值作为两个小数组的实际长度,不要用sizeof计算
  4. 打印数组时用实际长度作为循环上限,不要写死固定值

修正后的完整代码如下:

// Dividing a List into two Lists who's elements are <=X or >X
int main()
{
    int n;
    int boarder;
    int iList_1[] = {1, 23, 15, 90, 78, 234, 987, 2, 0, 13, 56};
    // 预分配和原数组等长的存储空间,初始值全置0
    int iList_2small[sizeof(iList_1)/sizeof(int)] = {0};
    int iList_3large[sizeof(iList_1)/sizeof(int)] = {0};
    // 计数器挪到循环外初始化
    int step_L2 = 0;
    int step_L3 = 0;

    //Calculate the number of elements in the array
    size_t len1 = sizeof(iList_1) / sizeof(int);
    printf("The Array iList_1 is %llu long\n", len1);

    //Where to divide the array?
    printf("At what value should the array iList_1 be split? (ONLY INTEGERS ALLOWED)\n");
    scanf("%i", &boarder);
    printf("\nConfirming boarder value of: %i \n\n", boarder);

    //Dividing the arrays at the boarder value
    for(n=0; n < len1; n++){
        if(iList_1[n] <= boarder){
            iList_2small[step_L2] = iList_1[n];
            step_L2 += 1;
        }
        else {
            iList_3large[step_L3] = iList_1[n];
            step_L3 += 1;
        }
    }

    // 计数器的值就是小数组的实际长度
    size_t len2 = step_L2;
    size_t len3 = step_L3;

    //Only for demonstration purposes
    printf("\nThe length of the small list is \t %llu \t elements", len2);
    printf("\nThe length of the large list is \t %llu \t elements\n", len3);

    //Outputting the sorted arrays
    printf("Small list elements: ");
    for(n = 0; n < len2 ; n++){
        printf("%i ", iList_2small[n]);
    }
    printf("\nLarge list elements: ");
    for(n = 0; n < len3; n++){
        printf("%i ", iList_3large[n]);
    }
    return 0;
}

补充说明:不要直接把Python动态列表的使用逻辑套用到C语言静态数组上,C语言数组声明后长度固定,写入元素时不能超过声明的长度,否则就会触发越界的未定义行为,可能出现各种不符合预期的运行结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 04:39:17