返回malloc分配的指针后是否需调用free?复用地址会有问题吗?
问题解答
代码里的两个明显问题
return后的free(t)永远不会执行:函数执行到return t就直接返回了,后续代码完全不会运行,这块堆内存会处于内存泄漏状态——分配后从未被释放。- 数组越界写入:你分配的内存大小是
length(a)+length(b)+1,合法索引范围是0到length(a)+length(b)(数组从0开始计数),但你写了t[length(a)+length(b)+1] = '\0';,这已经超出分配的内存边界,会触发未定义行为,可能破坏堆结构或其他数据。
核心疑问解答
1. 已释放的内存会不会被malloc复用?
会的。内存分配器会把释放的内存加入空闲内存池,后续调用malloc时,如果有匹配大小的空闲块,会优先复用这些内存,而非向操作系统申请新内存。
2. 若z指向已释放的地址,后续malloc复用该地址会引发问题吗?
肯定会。调用free(z)后,z就成了野指针——指向的内存不再属于当前程序的有效内存范围。如果后续malloc复用这个地址:
- 再通过
z读写这块内存,会篡改新分配变量的数据,导致逻辑混乱甚至程序崩溃; - 新分配的变量会覆盖这块内存的数据,若你还以为
z指向原来的字符串,读取到的会是错误内容。
3. 返回malloc分配的指针后是否需要调用free()?
必须要。malloc分配的堆内存不会像栈变量一样随函数结束自动释放,conc函数返回指针后,内存的释放责任就转移给了调用者——也就是main函数里,你需要在使用完z之后调用free(z);,否则内存会一直被占用,直到程序结束才会被操作系统回收。
修正后的代码示例
#include <string.h> #include <stdlib.h> #include <stdio.h> char *conc(char *a, char *b){ size_t len_a = strlen(a); size_t len_b = strlen(b); // 分配内存,同时检查malloc是否成功 char *t = malloc(len_a + len_b + 1); if (t == NULL) { return NULL; } // 拷贝字符串a for(size_t i = 0; i < len_a; i++){ t[i] = a[i]; } // 拷贝字符串b for(size_t j = 0; j < len_b; j++){ t[len_a + j] = b[j]; } // 正确设置字符串终止符 t[len_a + len_b] = '\0'; return t; } int main (void){ char *x = "he"; char *y = "llo dude"; char *z = conc(x, y); if (z != NULL) { // 使用z printf("%s\n", z); // 使用完毕释放内存 free(z); z = NULL; // 置空避免野指针 } return 0; }
内容的提问来源于stack exchange,提问作者Sarvesh Pande
相关产品推荐
相关产品推荐

