递归函数执行后释放动态数组array3出现Free Memory array error
问题
递归函数Mirage用于从array1和array2中依次取字符填充动态创建的array3,直至其中一个数组耗尽,功能可正常运行,但调用free()释放array3时出现释放内存数组错误。以下是代码:
void Mirage(char list1[], char list2[], char list3[], int m, int n); int main() { char array[7] = { 'a','b','c','d','e','f','g' }; char array2[3] = { 'T','Z','W' }; char *array3 =(char*) malloc(sizeof(array)+sizeof(array2)); Mirage(array, array2, array3, 7, 3); printf("%s", array3); free((void*)array3); } void Mirage(char list1[], char list2[], char list3[], int m, int n) { if ((m <= 0) && (n <= 0)){ list3[m + n] = 0; return; } else if (m >= 0 && n <= 0) { list3[0] = list1[0]; Mirage(list1 + 1, list2, list3 + 1, m - 1, n); } else if (m <= 0 && n >= 0) { list3[0] = list2[0]; Mirage(list1, list2+1, list3 + 1, m, n-1); } else { list3[0] = list1[0]; list3[1] = list2[0]; Mirage(list1 + 1, list2 + 1, list3 + 2, m - 1, n - 1); } }
报错原因
- 越界写入破坏堆结构
递归终止时的list3[m + n] = 0;是核心问题。当递归到最终阶段,m和n都会变成负数(比如初始m=7、n=3,循环到n=0后,m会继续减到0再变成-3,此时n=-3),m+n会得到负数索引,这会往list3的堆内存边界外写入数据,直接破坏了堆的管理表头,导致free()时检测到内存结构异常报错。 - 边界条件判断错误
原代码中m >= 0、n >= 0的判断会导致当m或n等于0时,仍尝试访问list1[0]或list2[0],此时数组已经越界,可能进一步破坏内存。
修复方案
1. 修正终止符写入位置
递归终止时,直接往当前list3的起始位置写入字符串终止符:
if ((m <= 0) && (n <= 0)){ list3[0] = '\0'; return; }
2. 调整递归边界判断
将条件改为m > 0和n > 0,避免越界访问数组:
else if (m > 0 && n <= 0) { list3[0] = list1[0]; Mirage(list1 + 1, list2, list3 + 1, m - 1, n); } else if (m <= 0 && n > 0) { list3[0] = list2[0]; Mirage(list1, list2+1, list3 + 1, m, n-1); }
3. 优化内存分配(可选)
按实际需要分配内存,拼接后的字符串需要7+3+1=11字节(含终止符),无需分配两个数组的总字节数:
char *array3 = malloc(7 + 3 + 1); // C标准中无需强制转换malloc的返回值
内容的提问来源于stack exchange,提问作者Bubi
相关产品推荐
相关产品推荐

