我正在编写一个动态分配的 C 程序
有人可以解释一下如何修复“goto”中的内存泄漏
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
int main()
{
printf("start main\n");
char *f = NULL;
L1:
f = (char *)malloc(10);
if (f == NULL)
return -1;
printf("body lebel\n");
f = "A";
if (f == "B") {
free(f);
goto L1;
}
return 0;
return 0;
}
valgrind --leak-check=full ./a.out
,
输出:
==7217== HEAP SUMMARY:
==7217== in use at exit: 10 bytes in 1 blocks
==7217== total heap usage: 2 allocs, 1 frees, 1,034 bytes
allocated
最佳答案
第一
f = "A";
将字符指针f
指定为指向"A"
,它是一个位于进程镜像中某处的const char*
。这完全孤立了您使用 malloc
分配的内存。要将字符串 "A"
复制到 f
指向的内存,您需要编写类似
strcpy(f, "A");
或
strncpy(f, "A", 10);
需要注意的是,strcpy
可能会超出为 f
分配的缓冲区,而 strncpy
可能会使其非空终止。
其次,在跳转到 L1
之前,您只需释放 if 语句内的 f
即可。要在程序退出之前释放 f
,您还必须在 return 0
之前编写 free(f)
。
第三,f == "B"
检查f
是否指向 const char* 值"B"
,而不是其内容是否指向与“B”
相同。在您的程序中,这始终为 false,因为您在比较之前将其分配给 "A"
。您需要使用诸如 strcmp
之类的函数来处理以 null 结尾的字符串,或者使用 memcmp
来处理可能非 null 结尾的字符串。
也可以将第一个 free
移动到标签的开头,这样您就不必确保在跳转之前释放它,因为 free( NULL)
不执行任何操作。另外,为了后代的利益,您应该将 "A"
和 "B"
声明为变量,并将常量 10
也移动到变量中有助于防止将来发生内存违规:
int main()
{
const char a_str[] = "A";
const char b_str[] = "B";
size_t buffer_size = 10;
printf("start main\n");
char *f = NULL;
L1:
free(f);
f = (char *)malloc(buffer_size);
if (f == NULL)
return -1;
printf("body lebel\n");
if (buffer_size < sizeof(a_str)) {
printf("Buffer too small for %s\n", a_str);
exit(1);
}
memcpy(f, a_str, sizeof(a_str));
if (buffer_size < sizeof(b_str)) {
printf("Buffer too small for comparison with %s\n", b_str);
exit(1);
}
if (!memcmp(f, b_str, sizeof(b_str)) {
goto L1;
}
free(f);
return 0;
}
关于c - 如何修复C中的 ‘memory leak’,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56413274/