C语言动态内存分配实现子集全打印的代码问题求助
集合子集打印代码的动态内存错误修复
为啥你的代码会崩?
- 栈内存非法释放:
printAllSubsets里的subset是栈上数组,你在subsetUtil里直接free(subset)——栈内存不是malloc分配的,绝对不能用free释放,一执行就触发未定义行为。 - 内存拷贝字节数不足:
memcpy(newTemp,subset,Subsize)没乘sizeof(int),本来要拷贝Subsize个整数,结果只拷贝了Subsize个字节,数据直接乱掉。 - 冗余内存操作搞乱指针:递归返回后反复malloc新内存拷贝原子集,纯纯多此一举,还会导致指针混乱和内存泄漏。
- 初始子集未初始化:第一个打印的是栈数组里的垃圾值,连空子集都没正确输出。
修正后的代码(完全保留原递归算法逻辑)
#include <stdio.h> #include <stdlib.h> #include <string.h> void printArray(int* arr, int size) { if (size == 0) { printf("空子集\n"); return; } for (int i = 0; i < size - 1; i++) { printf("%d ", arr[i]); } printf("%d\n", arr[size - 1]); } void subsetUtil(int* arr, int* subset, int index, int arrSize, int subSize) { printArray(subset, subSize); for (int i = index; i < arrSize; i++) { // 为扩展后的子集分配内存,比原大小多1 int* newSubset = malloc((subSize + 1) * sizeof(int)); // 拷贝原子集内容 memcpy(newSubset, subset, subSize * sizeof(int)); // 添加当前元素到新子集 newSubset[subSize] = arr[i]; // 递归处理后续元素 subsetUtil(arr, newSubset, i + 1, arrSize, subSize + 1); // 递归完成后释放当前扩展的子集,避免内存泄漏 free(newSubset); } // 释放当前子集(仅堆分配内存,合法安全) free(subset); } void printAllSubsets(int* arr, int size) { int index = 0; // 初始空子集用堆分配,确保后续free操作合法 int* emptySubset = malloc(0); subsetUtil(arr, emptySubset, index, size, 0); } int main(void) { int baseArray[10] = {1,2,3,4,5,6,7,8,9,0}; printAllSubsets(baseArray, 10); return 0; }
关键修改说明
- 初始子集改用堆分配:把原来的栈数组换成
malloc(0)的空子集,既保证后续free操作合法,又能正确打印空子集。 - 砍掉冗余内存操作:删除原代码中多余的
temp和newTemp内存分配,递归前仅分配一次新子集,递归完成后直接释放,逻辑清晰且避免内存混乱。 - 补全内存拷贝字节数:所有
memcpy操作都明确使用size * sizeof(int)作为拷贝长度,彻底解决数据截断和越界问题。 - 增加空子集打印逻辑:在
printArray中处理size=0的情况,输出符合预期的空子集。
内容的提问来源于stack exchange,提问作者user16377193
相关产品推荐
相关产品推荐

