以下程序没有内存泄漏。我的问题是,即使我同时分配了两个字符串,为什么也不必将str1和str2传递给free()?请在代码中我尝试释放str1和str2的地方看到两个注释的位置,取消注释该代码导致错误,提示我释放了一个非堆对象。但是据我了解,str1和str2是malloc创建的对象,因此是堆对象。我不明白这个矛盾。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* StrCat(char* s1, const char* s2) {
// Removing const from const char* s2
// made no difference on memory leak error message
char *s, *tmp;
s = tmp = malloc(strlen(s1) + strlen(s2) + 1);
strcpy(tmp, s1);
tmp += strlen(s1);
strcpy(tmp, s2);
//free(str1); free(str2); Why not?
printf("%d\n", s[strlen(s)] == '\0'); // Prints 1
return s;
}
int main(int argc, char** argv) {
char* str1 = malloc(4 * sizeof (char));
str1 = "abc\n";
char* str2 = malloc(6 * sizeof (char));
str2 = "party\n";
char* new = StrCat(str1, str2);
//free(str1); free(str2); Why not?
printf("%s\n", new);
free(new); // Required
return 0;
}
答案 0 :(得分:1)
当然,无论是否将其传递给函数,都需要释放堆对象。无论malloc()
返回什么,最终都必须free()
,无论您将如何使用它。
您的问题如下:
以下行:
char* str1 = malloc(4 * sizeof (char));
为4个字符分配内存,并将对它的引用存储在str1
中。
以下行:
str1 = "abc\n";
忘记str1
指向的任何内存(从而导致内存泄漏),并使str1
指向程序的静态数据段中的新位置。这是从未分配过的内存,因此可能无法释放。
为了解决您的问题,而不是将str1
设置为指向"abc\n"
的情况,您需要使用strcpy()
将"abc\n"
复制到指向的已分配存储块中由str1
。
在执行此操作之前,请不要忘记将4
和6
分别增加1,因为C中的字符串还包含一个以零结尾的字节,因此您需要为{{ 1}}和5
个字符。