The*_*nus 5 c memory-management
如果变量已经malloc过去,那么如果malloc再次调用它而不是realloc?它会导致内存泄漏吗?
我想知道,以便我可以在malloc调用传递给函数的参数之前添加检查,以避免潜在的泄漏.
void memtest(char **foo)
{
if ( foo )
*foo = malloc(10); // Assuming *foo was already allocated in the past.
}
Run Code Online (Sandbox Code Playgroud)
我应该总是做以下事吗?
void memtest(char **foo)
{
if ( foo ) {
if ( *foo ) {
free(*foo);
*foo = NULL;
}
*foo = malloc(10);
}
}
Run Code Online (Sandbox Code Playgroud)
呼吁malloc无关紧要.
如果出现问题,问题是分配.在您完成之后,无论它有多重要,x=42;之前的值x都消失了.同样,如果foo你是某个内存的唯一指针,如果你覆盖foo,你就不能再访问那个内存了.
如果free不指定要释放的内容,则无法拨打电话.因此,如果你在失去唯一指针之前没有释放内存,那么你就无法释放它,这就是内存泄漏的定义.
没有"呼唤malloc变量"之类的东西.
malloc找到一些"自由"内存,将其标记为"已使用",并返回刚刚找到的内存开头的地址.free将一些"使用过的"记忆标记为"免费".
当你跑步
*foo = malloc(10);
Run Code Online (Sandbox Code Playgroud)
发生以下情况:
malloc 找到10个字节的可用内存.malloc 标记使用的那10个字节.malloc 返回刚刚找到的10个字节的起始地址.foo,这是一个地址,因为它foo是一个指针.malloc返回的地址存储在存储的地址中foo.malloc不能不关心你的程序对它返回的地址做了什么.它不关心你的程序是将它存储在一个简单的变量,一个数组,另一个malloced空间,还是将它写入一个文件.它甚至不关心你的程序忘记了地址,但你应该关心,因为free如果程序不知道它试图释放的内存的地址,你的程序将永远无法调用.
有了这些知识,你应该能够看到这段代码的作用:
char *bar;
bar = malloc(10);
bar = malloc(10);
free(bar);
Run Code Online (Sandbox Code Playgroud)
花点时间弄清楚,然后阅读下面的内容:
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);
Run Code Online (Sandbox Code Playgroud)
在这里,我称之为malloc"on"一个已经拥有malloced 的地址的变量.这是内存泄漏吗?不是单独的.程序可能仍然free是第一个存储块,其地址仍然存储在其中baz.
但是,这肯定是内存泄漏:
void func()
{
char *bar;
char *baz;
bar = malloc(10);
baz = bar;
baz = malloc(10);
}
Run Code Online (Sandbox Code Playgroud)
我甚至没有改变代码,但只是把它放在一个函数中,它现在是一个内存泄漏!Whaaaaaaaaa?
记住内存泄漏究竟是什么.内存泄漏是指程序分配内存但从不释放内存.您无法通过查看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!
}
Run Code Online (Sandbox Code Playgroud)
总之:标题中的问题没有意义.检测内存泄漏并不像这样简单.而你想要做的是一个坏主意.