2012-11-25 34 views
2

我用這個代碼玩:C內存管理更指向同一位置

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

void function(int *p){ 
    free(p); 
} 

int main(){ 
    int *i = calloc(3, sizeof(int)); 
    function(i); 
    i[0] = 'a'; 
    printf("%c\n", i[0]); 
    return 0; 
} 

我希望得到一個錯誤,而是它印「A」,如果「一」被釋放爲什麼它打印它?如果main()?(如果可以的話,解釋'p'指針發生了什麼),函數(int * p)會發生什麼影響

假設我有這兩個函數:

int *a = malloc(...); 
int *b = a; 

他們都指向同一塊內存,但是當我不得不釋放它,我應該叫免費上他們兩個,或只是其中之一?(又爲什麼如果可能的解釋)

回答

3

您已經將內存返回到堆中,但內存未被重用。所以,有時內存內容保持不變,你可以讀寫它,就好像它仍在使用中一樣。

但是你不應該使用已經釋放的內存,因爲不能保證內存以這種方式保留多長時間。

在你的第二部分a = malloc(...); b = a中,兩個變量都指向相同的內存。由於這只是一個字節片段,您必須free()它恰好是一次。否則你有一個雙倍免費,這可能會損壞堆。

更新爲@ SSHThis的問題:

free(a)只返回內存堆。它不修改ab。檢查if(a)if(b)的計算結果爲真,無論內存是否已釋放。只有當您將ab設置爲空時,檢查纔會評估爲false,內存是否已釋放。

所以free(a)if(a)是獨立的操作。他們不會互相影響。

a = malloc(10); /* assuming malloc doesn't return NULL */ 
if (a) { 
    /* will be true, memory is NOT freed */ 
} 

free(a); 
if (a) { 
    /* will be true, although memory is freed */ 
} 

a = malloc(10); /* assuming malloc doesn't return NULL */ 
a = NULL; 
if (a) { 
    /* will NOT be true, although memory is NOT freed */ 
} 
+0

謝謝你的明確的答案,這讓我更有意義。我有一個徘徊的問題,可能不值得一個全新的問題。使用你的變量名例如,如果'b'可以等於'a'或'b'也可能等於一些新的malloc'ed內存,我可以免費(a)'然後做一個像'如果(b)免費(b)'?我假設如果前者是真的,'a'會被釋放,因此'如果(b)'不會評估爲真? –

+0

@SSHThis請參閱最新的答案。 –

+0

非常感謝你 –

5

這是未定義的行爲。釋放指針只是告訴操作系統分配的內存可以被覆蓋。記憶仍然存在......缺乏一個更好的詞彙。但是任何事情都可能發生......現在它可能會爲您打印一個文件,在其他時候它可能是另一個字符或數字,因爲另一個程序已經寫入了該內存位置......任何事情都可能發生。

對於你最後的問題.. a和b只是一個地址的符號名稱。免費撥打地址非常重要,因此無論您是做free(a)還是free(b),您都是盛大的。

3

它打印'a',因爲你很幸運。這是未定義的行爲。它目前'取消分配',也就是說,它(內存位置)被標記爲'覆蓋'

2

你的代碼是錯誤的,但得到的錯誤意味着的東西是檢查是錯誤的。在C中有很多事情你可以做是錯誤的,但從不被檢查。這通常是因爲執行檢查會導致性能損失,或者檢查是非常困難的。訪問已釋放的內存就是其中之一。通過像valgrind這樣的工具來運行你的程序會報告更多這類問題,但程序運行速度會更慢。

這裏是從Valgrind的輸出:

==19080== Invalid write of size 4 
==19080== at 0x8048468: main (main.c:11) 
==19080== Address 0x403b028 is 0 bytes inside a block of size 12 free'd 
==19080== at 0x4006EED: free (vg_replace_malloc.c:366) 
==19080== by 0x8048434: function (main.c:5) 
==19080== by 0x8048463: main (main.c:10) 
==19080== 
==19080== Invalid read of size 4 
==19080== at 0x8048472: main (main.c:12) 
==19080== Address 0x403b028 is 0 bytes inside a block of size 12 free'd 
==19080== at 0x4006EED: free (vg_replace_malloc.c:366) 
==19080== by 0x8048434: function (main.c:5) 
==19080== by 0x8048463: main (main.c:10) 
==19080==