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

C语言中结构体含多成员时结构体数组无法排序的问题

结构体多成员时归并排序崩溃的原因与解决方法

当结构体仅包含int number成员时,归并排序代码可以正常运行,但为结构体添加char name[101]成员后,程序运行时会崩溃并返回非0值。

崩溃原因

核心问题是临时数组tempArr的大小计算错误:
合并区间[left, right]包含的元素总数是right - left + 1个,但代码里定义临时数组为name tempArr[right - left];,数组大小少了1。

当结构体只有单个int成员时,栈内存的越界写入可能刚好没有破坏关键数据(属于未定义行为,只是碰巧没崩溃);但结构体新增char[101]成员后,单个结构体占用内存大幅增加,越界写入会直接破坏栈上的其他数据(比如函数的返回地址、其他局部变量),触发程序崩溃。

另外还有两个非崩溃但不符合C语言规范的问题:

  • C语言中,结构体类型struct name不能直接简写为name,需要通过typedef定义别名,否则所有使用name的地方都要写成struct name
  • 函数参数里的name arr[5]会被编译器视为name *arr,写name arr[]或name *arr更符合语义

修复步骤

  1. 修正临时数组大小:将name tempArr[right - left];改为name tempArr[right - left + 1];,确保能容纳所有待合并的元素
  2. 规范结构体类型使用:添加typedef定义结构体别名,或者在代码中统一使用struct name
  3. 可选优化:将函数参数的数组写法改为指针形式,提升代码规范性

修复后的完整代码

#include <stdio.h>
#include <string.h>

// 添加typedef,让name可以直接作为结构体类型名
typedef struct name{
    int number;
    char name[101];
} name;

// 数组参数改为指针形式,更规范
void mergeSort(name *arr, int left, int right){
    if(left == right){
        return;
    }
    
    int middle = (right - left) / 2 + left;
    mergeSort(arr, left, middle);
    mergeSort(arr, middle+1, right);
    
    int leftIdx = left,
        leftLimit = middle,
        rightIdx = middle+1,
        rightLimit = right,
        tempIdx = 0;
    // 修正临时数组大小:right - left + 1
    name tempArr[right - left + 1];
        
    while(leftIdx <= leftLimit && rightIdx <= rightLimit){
        // 依然按number字段排序,不受新增成员影响
        if(arr[leftIdx].number < arr[rightIdx].number){
            tempArr[tempIdx] = arr[leftIdx];
            tempIdx++;
            leftIdx++;
        }else{
            tempArr[tempIdx] = arr[rightIdx];
            tempIdx++;
            rightIdx++;
        }
    }
    
    while(leftIdx <= leftLimit){
        tempArr[tempIdx] = arr[leftIdx];
        tempIdx++;
        leftIdx++;
    }
    while(rightIdx <= rightLimit){
        tempArr[tempIdx] = arr[rightIdx];
        tempIdx++;
        rightIdx++;
    }
    
    tempIdx = 0;
    for(int i=left; i<=right; i++){
        arr[i] = tempArr[tempIdx];
        tempIdx++;
    }
}

int main(){
    name arr[5];
    
    // 示例输入逻辑:可以同时输入number和name
    for(int i=0; i<5; i++){
        scanf("%d %s", &arr[i].number, arr[i].name);
    }
    
    mergeSort(arr, 0, 4);
        
    // 输出排序后的结果
    for(int i=0; i<5; i++){
        printf("%d %s\n", arr[i].number, arr[i].name);
    }
    
    return 0;
}

说明

修复后,无论结构体有多少个成员,只要排序逻辑是基于number字段(或你指定的其他字段),归并排序都能正常运行。如果需要按其他字段排序,只需要修改合并时的比较条件即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 09:05:19