2016-09-25 76 views
0

我想了解從函數調用返回指針的行爲。假設我有以下簡單的代碼:在返回語句之前瞭解空閒()緩衝區

int main(){ 
    int i; 
    float *ssd; 
    ssd = test(); 

    for (i = 0; i < 3; ++i) { 
     printf("%f, ", ssd[i]); 
    } 
    printf("\n \n"); 

    memset(ssd, 0.0, 3*sizeof(float)); 

    for (i = 0; i < 3; ++i) { 
     printf("%f, ", ssd[i]); 
    } 
    printf("\n \n"); 

} 

float *test(){ 

    float *buff = malloc(3* sizeof(float)); 
    int i; 
    for (i = 0; i < 3; ++i) { 
     buff[i] = (float) (6.31 + i); 
    } 

    free(buff); 
    return buff; 

} 

正如你看到的,我創建了一個臨時緩衝區內bufftest()。在我回來之前,我在return聲明之前釋放了buff。儘管我測試了它並且結果如預期,但我不明白test()函數如何返回buff值,即使free(buff)return之前buff?

+0

相關:http://stackoverflow.com/q/6441218/509868 – anatolyg

+2

沒有與不確定的行爲一個C程序是不可能的。 – PSkocik

+2

這是不正確的代碼。它會導致腐敗。這似乎是免費的錯誤後使用 –

回答

5

free(buff); 

任何進一步的操作,其提領buff未定義行爲

你的功能test()分配一個緩衝區,但隨後free其返回到main,爲ssd之前這樣。

因此,當ssdmain中被取消引用時,雖然指針仍然具有相同的值,但它已被分配malloc,它不再指向您擁有的存儲器。所以從那時起,任何事情都可能發生。您的代碼可能仍然有效,或者可能不會。

+0

謝謝你的解釋。在這種情況下,請介紹一下解釋這種情況以避免模糊不清的最佳方法嗎?在'return'語句之後放置'free()'將無法正常工作,所以我不知道下一步該怎麼做! – Adam

+0

在完成使用其內容後,您只能「釋放」內存。只要'main'中'ssd'的值沒有改變,當你沒有進一步的使用時,你可以在'main'中'free(ssd)',因爲它仍然有和'buff'相同的指針值= malloc(3 * sizeof(float))'在函數中。 –

+0

@亞當如果你想知道「如何修正你的代碼」,而不是「什麼是錯的」,請問一個單獨的問題。您可能想要返回一個數組(使用[此處](http://stackoverflow.com/q/11656532/509868)或[這裏](http://stackoverflow.com/q/8617889/509868)中描述的技術)你的函數,而不是使用'malloc'和'free'。 – anatolyg

0

最初由buff指向的內存不會被覆蓋,因此會保留您存儲在其中的值。

這通常是我們所說的「包含垃圾的內存」,但是自從初始化它然後一切正常。

0

從libc中的文檔,

偶爾,免費其實可以返回內存操作系統 ,使過程更小。通常,它所能做的只是允許稍後調用malloc以重新使用空間 。與此同時,程序中的空間仍然是 ,作爲malloc內部使用的自由列表的一部分。

免費電話並不能保證空間被清理。但是,什麼是保證(至少由GNU libc實現)是

  1. 從而釋放將可能使用的任何動態內存分配例程的將來調用運行空間。

爲了證明這一點,我修改了你的程序如下。它基本上在你的test()函數中添加了一個for循環,該函數剛分配n次並釋放該buff(e.x.10次),並打印緩衝區的內容。所以每次運行程序時,它都會首次打印內容,當malloc()和free()被調用時,* buff的內容被清除並且垃圾被打印。 (在Mac上測試,gcc 4.8+)。 希望這有助於。

#include<stdlib.h> 
 
#include<stdio.h> 
 
#include<string.h> 
 
float *test(){ 
 
    float *buff = malloc(3* sizeof(float)); 
 
    int i, j; 
 
    for (i = 0; i < 3; ++i) { 
 
    buff[i] = (float) (6.31 + i); 
 
    } 
 
    free(buff); 
 
    int n = 10; 
 
    for(i=0;i<n;i++) 
 
    { 
 
    printf("Iteration %d ", i); 
 
    for (j = 0; j < 3; ++j) { 
 
     printf("%f, ", buff[i]); 
 
    }  
 
    printf("\n"); 
 
    buff = malloc(3 * sizeof(float)); 
 
    free(buff); 
 
    } 
 
    return buff; 
 

 
} 
 
int main(){ 
 
    int i; 
 
    float *ssd; 
 
    ssd = test(); 
 
    printf("\n \n"); 
 
    memset(ssd, 0.0, 3*sizeof(float)); 
 
    for (i = 0; i < 3; ++i) { 
 
    printf("%f, ", ssd[i]); 
 
    } 
 
    printf("\n \n"); 
 
}