没有“在变量上调用malloc”这样的东西。
malloc 找到一些“空闲”内存,将其标记为“已使用”,并返回它刚刚找到的内存的起始地址。 free 将一些“已用”内存标记为“空闲”。
当你跑步时
*foo = malloc(10);
会发生以下情况:
-
malloc 找到 10 字节的空闲内存。
-
malloc 将这 10 个字节标记为已使用。
-
malloc 返回它刚刚找到的 10 个字节的起始地址。
-
您的程序查看
foo 的值,这是一个地址,因为foo 是一个指针。
-
您的程序将返回的地址
malloc 存储在存储在 foo 中的地址中。
malloc 不在乎你的程序如何处理它返回的地址。它不关心你的程序是否将它存储在一个简单的变量、一个数组、另一个malloced 空间中,甚至将它写入文件。它甚至不关心你的程序是否忘记了地址,但你应该关心,因为如果你的程序不知道它试图释放的内存地址,它将永远无法调用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 称为“on”一个变量,该变量已经保存了malloced 的地址。那么这是内存泄漏吗?不是自己。程序可能仍然free第一个内存块,其地址仍然存储在baz中。
但是,这绝对是内存泄漏:
void func()
{
char *bar;
char *baz;
bar = malloc(10);
baz = bar;
baz = malloc(10);
}
我什至没有更改代码,但只是将它放在一个函数中,它现在是内存泄漏!哇啊啊啊?
记住内存泄漏实际上是什么。内存泄漏是指程序分配内存但从未释放它。您无法仅通过查看 malloc 调用来判断程序是否释放了所有内存。
至于第二部分——“我应该这样做吗?”
不,你不应该。
只有当传递给你的函数的地址的旧值是malloced 指针时,它才会起作用,并且如果调用者忘记了free它。
您的建议将破坏以下任何功能:
void func1()
{
char c;
char *ptr = &c;
memtest(&ptr); // Tries to free something that wasn't malloced!
// ... do something with ptr ...
}
void func2()
{
char *ptr;
memtest(&ptr); // Passes a garbage address to free!
// ... do something with ptr ...
}
void func3()
{
char *ptr1 = malloc(5)
char *ptr2 = ptr1;
memtest(&ptr1);
// ... do something with ptr1 and ptr2 ...
free(ptr1); // Frees memory that was already freed!
}
结论:标题中的问题没有意义。而检测内存泄漏并不是这么简单。而你正在尝试做的是一个坏主意。