2011-11-21 51 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()通常會嘗試將你新釋放的「內存塊」插入到某些數據結構中,這通常涉及一些寫入位置,你通過的指針附近)。
  • 這兩個極端之間的任何東西。不應以錯誤終止應被視爲差於終止。