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; }
代码说明
- 排序:将男女身高从小到大排序,确保贪心策略的正确性——给最矮的男生匹配能符合条件的最矮女生,最大化剩余女生的适配性。
- 双指针遍历:用两个指针分别遍历男生和女生数组,找到符合条件的配对后同时移动指针,否则仅移动女生指针。
- 内存管理:每组测试用例结束后立即释放分配的内存,避免泄漏。
- 结果判断:统计成功配对的男生数量,若等于男生总数则输出YES,否则输出NO。
内容的提问来源于stack exchange,提问作者VortexX Bolt
相关产品推荐
相关产品推荐

