2011-11-21 39 views
3

如果尝试释放未使用malloc/calloc分配的内存,会发生什么情况?与C中的free()相关的查询

这里是我的意思是:

void main() 
{ 
int temp = 0; 
int *ptr = &temp; 
free(ptr); 
} 

我想free()会返回一些错误代码,但free()没有返回值。

+1

你希望C会像Python或Java一样慢。如果这就是你想要的,使用其中的一种语言。否则,请带上红色药丸并潜入一个美妙的世界,在这个世界中,您实际上必须承担责任,尊重您使用的界面的合同一方。 –

+1

“尝试想像所有生命,因为你知道它瞬间停止,并且你身体中的每个分子都以光速爆炸。” (http://en.wikipedia.org/wiki/Proton_packs#Crossing_the_Streams) –

+2

@R:我刚刚问了一个问题。我不是在抱怨C。 –

回答

8

如果您在以前未分配的指针上调用free(),则会触发未定义的行为。

Linux man pages

的free()函数释放内存空间由PTR,必须已返回由以前调用malloc()函数,释放calloc()或realloc指出,()。否则,或者如果释放(ptr)之前已被调用,则会发生未定义的行为。如果ptr为NULL,则不执行任何操作。

+0

人们可以阅读很多网页上的这种说法,但有没有任何“官方证据”呢? – kol

+0

是的,看我的编辑。 – Malcolm

+0

@kol:有关权威参考请参阅我的答案(http://stackoverflow.com/questions/8214692/query-related-to-free-in-c/8214963#8214963)。 –

2

我扩展上面的代码位:

#include <stdio.h> 
#include <stdlib.h> 

void main() 
{ 
    int temp = 0; 
    int *ptr = &temp; 
    printf("Before: %0X\n", ptr); 
    free(ptr); 
    printf("After: %0X\n", ptr); 
    getchar(); 
} 

如果这个代码是由Visual Studio 2010中编译,在调试配置,调用free启动“调试断言失败”的消息。此错误消息来自dbgheap.c:

/* 
* If this ASSERT fails, a bad pointer has been passed in. It may be 
* totally bogus, or it may have been allocated from another heap. 
* The pointer MUST come from the 'local' heap. 
*/ 
_ASSERTE(_CrtIsValidHeapPointer(pUserData)); 

使用MinGW-GCC编译,生成的exe文件运行没有错误(“后:...”线显示PTR为“以前相同的值。 ..“行)。

0

除了通过Malcom和undur_gongor的答案,Windows上的Visual Studio中的C也是一样的。从MSDN的描述相关的部分被发现here

自由功能将释放以前由于释放calloc,malloc或realloc一个呼叫分配的内存块(memblock)。释放的字节数相当于分配块时要求的字节数(或realloc时重新分配的字节数)。如果memblock为NULL,则该指针被忽略并立即返回。尝试释放无效指针(指向未由calloc,malloc或realloc分配的内存块的指针)可能会影响后续分配请求并导致错误。

1

所有的地狱都会破裂。

这意味着:

  • 如果幸运的话,你的程序将因错误而终止。
  • 如果你不幸运,一些攻击者将使用你的程序执行任意代码(free()通常会尝试将你新释放的“内存块”插入到某些数据结构中,这通常涉及一些写入位置,你通过的指针附近)。
  • 这两个极端之间的任何东西。不应以错误终止应被视为差于终止。