如何修复我的内存泄漏?
How do I fix my memory leak?
我有
int main(void){
while (1){
char *input = NULL;
char buf[1000];
int read;
size_t len;
read = getline(&input, &len, stdin);
if (-1 != read){
sprintf(buf, "%s", input);
lowercase(buf);; // custom function
get_command(buf); // custom function already checked for memory leak
}
free(stdin);
free(input);
free(buf);
}
return 0;
}
运行 这通过 valgrind returns:
HEAP SUMMARY
by 0x4022c2: main(prog.c:647) // read = getline(&input, &len, stdin);
LEAK SUMMARY
still reachable: 120 bytes in 1 blocks
既然我释放了一切(stdin、输入、buf),为什么它仍然给我内存泄漏?我该如何解决这个问题?
在评论中,您说您从函数 get_command
中调用了 exit(0)
。调用 exit(x)
的行为就像程序 return 从 main
编辑 x
一样。这意味着您跳过 main
.
末尾的清理代码
为了解决这个问题,您可以 return 来自 get_command
的值,例如 0 表示正常操作,-1 表示错误或 1 表示输入结束。这意味着 get_command
中的 exit(0)
现在变成 return 1
.
您的 main
循环可能如下所示:
int main(void)
{
char *input = NULL;
size_t len = 0;
while (1) {
if (getline(&input, &len, stdin) < 0) break;
lowercase(input);
if (get_command(input) == 1) break;
}
free(input);
return 0;
}
请注意,我已经修复了您的代码的一些其他问题:
- 不要使用固定大小的临时缓冲区。
getline
可以读取任意长度的行。如果将这些复制到临时缓冲区,至少要确保它适合;毕竟,您已经获得了 len
信息。直接用input
字符串就更好了
- 不要每次调用
getline
时都从 NULL
缓冲区开始。这将减少分配的次数,因为只有当一行比之前读取的每一行都长时才会分配新内存,这种情况不应该经常发生。这也意味着 free
应该在循环之后。
我有
int main(void){
while (1){
char *input = NULL;
char buf[1000];
int read;
size_t len;
read = getline(&input, &len, stdin);
if (-1 != read){
sprintf(buf, "%s", input);
lowercase(buf);; // custom function
get_command(buf); // custom function already checked for memory leak
}
free(stdin);
free(input);
free(buf);
}
return 0;
}
运行 这通过 valgrind returns:
HEAP SUMMARY
by 0x4022c2: main(prog.c:647) // read = getline(&input, &len, stdin);
LEAK SUMMARY
still reachable: 120 bytes in 1 blocks
既然我释放了一切(stdin、输入、buf),为什么它仍然给我内存泄漏?我该如何解决这个问题?
在评论中,您说您从函数 get_command
中调用了 exit(0)
。调用 exit(x)
的行为就像程序 return 从 main
编辑 x
一样。这意味着您跳过 main
.
为了解决这个问题,您可以 return 来自 get_command
的值,例如 0 表示正常操作,-1 表示错误或 1 表示输入结束。这意味着 get_command
中的 exit(0)
现在变成 return 1
.
您的 main
循环可能如下所示:
int main(void)
{
char *input = NULL;
size_t len = 0;
while (1) {
if (getline(&input, &len, stdin) < 0) break;
lowercase(input);
if (get_command(input) == 1) break;
}
free(input);
return 0;
}
请注意,我已经修复了您的代码的一些其他问题:
- 不要使用固定大小的临时缓冲区。
getline
可以读取任意长度的行。如果将这些复制到临时缓冲区,至少要确保它适合;毕竟,您已经获得了len
信息。直接用input
字符串就更好了 - 不要每次调用
getline
时都从NULL
缓冲区开始。这将减少分配的次数,因为只有当一行比之前读取的每一行都长时才会分配新内存,这种情况不应该经常发生。这也意味着free
应该在循环之后。