我不确定为什么Valgrind会报告内存泄漏?
.c文件中的伪代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* str_alloc(char *str) {
char* dup = (char*) malloc((strlen(str) + 1) * sizeof(char));
strcpy((char*) dup, (char*) str);
return dup;
}
void function_c(char **name) {
int len = 10;
(void) realloc(*name, 100);
}
void function_b(char **name) {
(void) function_c(name);
}
void function_a(char **name) {
(void) function_b(name);
}
int main() {
char* name = str_alloc("");
function_a(&name);
// Do something with name
free(name);
}
我忽略了realloc的值,因为我确定realloc将始终位于同一指针上。从我自己的内存池分配/重新分配,这是非常大的。
当然,我不能在这里编写内存池的代码。
那么,在什么情况下我会因为Valgrind泄漏而来?我想到的几个案例:
还有其他情况吗?
答案 0 :(得分:3)
存在内存泄漏,因为您丢失了realloc
分配的内存。
realloc
的语法如下。
void *realloc(void *ptr, size_t size);
注意:不能保证realloc
返回的指针与传递给realloc
的旧指针相同,并且不应依赖于该指针。
甚至编译器也会警告您同样的情况。
警告:忽略使用属性声明的“ realloc”的返回值 warn_unused_result [-Wunused-result]
(void) realloc(*name, 100); ^
因此,您需要按以下方式修改function_c
函数。
void function_c(char **name)
{
char *newPtr = NULL;
newPtr = realloc(*name, 100);
*name = newPtr;
}
答案 1 :(得分:2)
我忽略了realloc的值,因为我确定realloc将始终位于同一指针上。从我自己的内存池分配/重新分配,这是非常大的。
在使用标准malloc / realloc / free接口的代码中,您根本无法做出此假设,即使您认为自己提供了实现并且知道在受控条件下的行为,也是如此。未来从事代码工作的人(包括您自己,从您忘记了该项目的细节之后的几年以后)将假设您的代码如何使用标准接口并没有什么特别之处,他们可以将代码移至完全不同的C实现中而无需引入您的特殊malloc库。
此外,C库有权拒绝让您替换这些函数,这是导致您直接遇到的问题的原因:valgrind强制用malloc / realloc / free的 own 实现替换您拥有的任何东西,从不从realloc返回相同指针的实现。这是有意为的,以捕获此类错误。
如果要实现一个保证“调整分配大小不会移动分配”之类的内存池,则需要为所有函数赋予新名称(例如pool_alloc
,{{1} },pool_resize
。