“在变量上调用 malloc
”这样的说法是不存在的。
malloc
会找到一些“空闲”内存,标记为“已使用”,并返回刚找到的内存起始地址。free
会将一些“已使用”的内存标记为“空闲”。
当您运行以下命令时:
*foo = malloc(10)
以下是发生的事情:
malloc
找到了 10 个字节的空闲内存。
malloc
将这 10 个字节标记为已使用。
malloc
返回刚找到的 10 个字节的起始地址。
- 您的程序 查看
foo
的值,因为 foo
是一个指针,所以它是一个地址。
- 您的程序 将
malloc
返回的地址存储在存储在 foo
中的地址中。
malloc
并不关心您的程序对其返回的地址做了什么。它不关心您的程序是否将其存储在简单变量、数组、另一个 malloc
的空间中,甚至是写入文件。它甚至不关心您的程序是否忘记了该地址,但您应该关心,因为如果您的程序不知道要释放的内存的地址,它将永远无法调用 free
。
有了这些知识,您应该能够看出此代码的作用:
char *bar;
bar = malloc(10);
bar = malloc(10);
free(bar);
请您耐心思考,然后阅读以下内容:
声明了一个名为“bar”的变量,其类型为“char *”。
程序调用了“malloc”函数。
“malloc”函数找到10个自由字节并将它们标记为已使用。
“malloc”函数返回10个字节开始的地址。
程序将地址存储在“bar”中。(现在,“bar”包含了前10个字节的地址)
程序再次调用“malloc”函数。
“malloc”函数找到另外10个自由字节并将它们标记为已使用。
“malloc”函数返回10个字节开始的地址。
程序将地址存储在“bar”中。(现在,“bar”包含了第二组10个字节的地址)
程序调用“free”函数,并传递第二组10个字节的起始地址。
“free”函数将第二组10个字节标记为自由。
这是内存泄漏。第一组10个字节永远不会被释放。我可以确定它们永远不会被释放,因为程序不知道它们所在的地址。
那么这个程序怎么样呢?
char *bar;
char *baz;
bar = malloc(10);
baz = bar;
baz = malloc(10);
在这里,我已经对一个已经持有malloc
的地址的变量进行了"调用"。那么这是一种内存泄漏吗?单独来看不是。程序可能仍然可以free
第一个内存块,其地址仍然存储在baz
中。
但是,这绝对是一种内存泄漏:
void func()
{
char *bar;
char *baz;
bar = malloc(10);
baz = bar;
baz = malloc(10);
}
我甚至没有改变代码,只是将其放在一个函数中,现在它成为了一个内存泄漏!Whaaaaaaaaa?
要记住什么是内存泄漏。当程序分配内存但从未释放时,就会出现内存泄漏。你不能仅通过查看malloc
调用来确定程序是否释放了所有内存。
至于第二部分 - “我应该这样做吗?”
不应该这样做。
只有在调用方忘记free
并且地址传递给您的函数的旧值是malloc
指针时,您的建议才能生效。
您的建议将破坏以下任何一个函数:
void func1()
{
char c;
char *ptr = &c;
memtest(&ptr);
}
void func2()
{
char *ptr;
memtest(&ptr);
}
void func3()
{
char *ptr1 = malloc(5)
char *ptr2 = ptr1;
memtest(&ptr1);
free(ptr1);
}
总之:标题中的问题没有意义,检测内存泄漏也不是那么简单。你所尝试做的事情是一个不好的想法。