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

C语言中按值传递的结构体数组被函数修改的问题排查

问题分析与解决方案

问题根源

  • 在C语言中,数组作为函数参数传递时,本质是传递数组首元素的指针,并非按值传递整个数组副本。所以你在Opartenza函数里修改c[j]、c[j+1]的操作,直接作用于主函数中的原数组corse。
  • 代码中c[d] = c[j]属于数组越界访问,数组下标范围是0到d-1,访问c[d]会触发未定义行为,可能导致程序崩溃或数据错乱。

修正方案

要实现“不修改原数组,仅通过索引数组排序”的需求,核心是只操作索引数组,完全不改动原结构体数组。比较时通过索引访问原数组元素,交换的只是索引数组中的值。

修正后的函数代码:

void Opartenza(struct Corse c[], int d, int **O)
{
    int temp = 0;
    // 分配索引数组内存,先检查分配是否成功
    *O = (int *)malloc(d * sizeof(int));
    if (*O == NULL) {
        return;
    }
    // 初始化索引数组,对应原数组的下标
    for(int i = 0; i < d; i++)
        (*O)[i] = i;
    
    // 冒泡排序,仅操作索引数组
    for(int i = 0; i < d; i++)
    {
        // 优化冒泡排序,减少不必要的循环次数
        for(int j = 0; j < d - 1 - i; j++)
        {
            // 通过索引访问原数组元素进行比较
            if(strcmp(c[(*O)[j]].partenza, c[(*O)[j+1]].partenza) > 0)
            {
                // 仅交换索引数组中的值
                temp = (*O)[j];
                (*O)[j] = (*O)[j + 1];
                (*O)[j + 1] = temp;
            }
        }
    }
}

使用示例

调用后,需通过索引数组访问原数组来输出排序结果,而非直接遍历原数组:

case r_o_partenza:
    Opartenza(corse, dim, &Ordinamento);
    // 通过索引数组输出排序后的内容
    for(int i = 0; i < dim; i++)
        printf("%s\n", corse[Ordinamento[i]].partenza);
    // 用完后释放内存,避免泄漏
    free(Ordinamento);
    Ordinamento = NULL;
    break;

注意事项

  • 内存分配后必须检查是否成功,避免空指针访问。
  • 索引数组使用完毕后要调用free释放内存,防止内存泄漏。
  • 可给冒泡排序添加“是否已排序”的标志,提前终止循环,提升效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 22:12:53