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

C语言舞会配对代码调试:SIGSEGV内存错误排查求助

舞会配对代码SIGSEGV错误排查与修复

问题背景

题目要求:Riverfield Country Day School举办舞会,有M名男生和N名女生,每位男生需与比自己严格矮的女生一对一跳舞,判断是否所有男生都能找到舞伴。输入T组测试用例,每组含M、N及男女身高数组,输出YES/NO。
问题:编写的C语言代码修改语法错误后出现Exited with return code -11 (SIGSEGV)错误,请求排查。

核心错误分析

  • 二级指针操作错误:remove_girl函数中直接对二级指针girlHeights执行数组下标访问girlHeights[p],这是错误的——二级指针存储的是数组指针的地址,必须先解引用得到实际数组指针(*girlHeights)[p]才能访问元素。
  • sizeof滥用:sizeof(girlHeights)返回的是指针类型的字节数(通常为8),不是数组的元素数量或总长度。遍历数组时必须使用传入的numGirls参数,而非sizeof计算值。
  • 内存管理混乱:remove_girl函数中先尝试移动元素,随后又重新malloc新数组,但未拷贝原有有效元素,同时丢失了原数组的内存地址,导致内存泄漏+非法访问。
  • 配对逻辑漏洞:找到符合条件的女生后未终止内层循环,会重复为同一男生配对多个女生;且numGirls未在配对后递减,导致后续遍历数组越界。
  • 结果判断逻辑完全错误:int(sizeof(girlHeights)) - int(sizeof(boyHeights))比较的是两个指针的字节大小差,和剩余女生、男生数量毫无关系,无法正确判断配对结果。
  • 内存释放错误:free操作放在测试用例循环外部,每组测试用例重新分配内存后,前一组的内存块会泄漏,且最终仅释放最后一组的指针。

修正后的代码(贪心算法实现)

直接采用排序+双指针的贪心策略,避免动态删除数组的复杂操作,逻辑更清晰且效率更高:

#include <stdio.h>
#include <stdlib.h>

// 排序用的比较函数
int compareInt(const void *a, const void *b) {
    return *(int*)a - *(int*)b;
}

int main() {
    int testCases;
    scanf("%d", &testCases);

    for (int g = 0; g < testCases; g++) {
        int numBoys, numGirls;
        scanf("%d %d", &numBoys, &numGirls);

        int *boyHeights = (int*)malloc(sizeof(int) * numBoys);
        int *girlHeights = (int*)malloc(sizeof(int) * numGirls);

        // 读取男生身高
        for (int j = 0; j < numBoys; j++) {
            scanf("%d", &boyHeights[j]);
        }
        // 读取女生身高
        for (int j = 0; j < numGirls; j++) {
            scanf("%d", &girlHeights[j]);
        }

        // 对男女身高排序
        qsort(boyHeights, numBoys, sizeof(int), compareInt);
        qsort(girlHeights, numGirls, sizeof(int), compareInt);

        int boyIdx = 0, girlIdx = 0;
        int paired = 0;

        // 双指针贪心配对:给最矮的男生找能配对的最矮女生
        while (boyIdx < numBoys && girlIdx < numGirls) {
            if (girlHeights[girlIdx] < boyHeights[boyIdx]) {
                paired++;
                boyIdx++;
                girlIdx++;
            } else {
                // 当前女生太高,尝试下一个女生
                girlIdx++;
            }
        }

        // 判断是否所有男生都配对成功
        if (paired == numBoys) {
            printf("YES\n");
        } else {
            printf("NO\n");
        }

        // 每组测试用例结束后立即释放内存
        free(boyHeights);
        free(girlHeights);
    }

    return 0;
}

代码说明

  1. 排序:将男女身高从小到大排序,确保贪心策略的正确性——给最矮的男生匹配能符合条件的最矮女生,最大化剩余女生的适配性。
  2. 双指针遍历:用两个指针分别遍历男生和女生数组,找到符合条件的配对后同时移动指针,否则仅移动女生指针。
  3. 内存管理:每组测试用例结束后立即释放分配的内存,避免泄漏。
  4. 结果判断:统计成功配对的男生数量,若等于男生总数则输出YES,否则输出NO。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 17:10:25