2013-04-24 23 views
5

舊的問題,但我仍然有一些想法。C中的數組及其指針

char * getarrmal(void) 
{ 
    char *str; 
    str = (char *)malloc(10); 
    str[0] = 'a'; 
    str[1] = 'b'; 
    str[2] = 'c'; 
    str[3] = '\0'; 
    return str; 
} 

char * getarrdef(void) 
{ 
    char *str = "hello"; 
    return str; 
} 

char * getarrfix(void) 
{ 
    char str[10] = "world"; 
    return str; 
} 

三個功能。前兩個將返回字符串地址,字符串存儲在堆中,以便您可以繼續使用它,例如main()函數。

在上一個函數中,str是局部變量,不能使用返回的str。

我的問題是,當我回到調用前兩個函數時,我應該手動釋放它們嗎?很容易相信malloc的情況是這樣,但我不確定char * str =「hello」是否也是這種情況。

如果我使用getarrdef()而不釋放它的返回值,那麼我會不知何故發生內存泄漏?

+3

如果你分配了它,並且你沒有使用'malloc'(或它的一個堂兄弟)這樣做,那麼你就不要叫'free'。簡單。 – 2013-04-24 03:44:09

回答

3

不,你應該肯定不是嘗試釋放第二個。這是而不是存儲在堆中,而是它是一個字符串文字,並試圖釋放它是未定義的行爲。從C++11 7.21.3.3 The free function

...如果該參數不匹配的指針早些時候內存管理 函數返回,或者如果空間已經通過調用釋放釋放或realloc時, 行爲是不確定的。

對於第一個,是的,分配內存的責任與內存本身一起傳遞是一個很好的做法。這意味着如果有東西分配給你,然後負責釋放它。

就是這樣,即使你通過將它傳遞迴一個函數來釋放它,例如:delarrmal() - 通過這樣做,你已經賦予了該函數的責任來釋放它。

+0

感謝您的快速回復:)。那麼有趣的是,第二個函數中存儲的str在哪裏,調用者的棧? – coldguy 2013-04-24 03:53:04

+2

@coldguy,在前兩種情況下,'str'(指針)存儲在堆棧中,第三種情況下'str'(數組)存儲在那裏。然而,在前兩種情況下指針_指向_的不同(第三種情況是不相關的,因爲str不是指針(在函數內))。在第一種情況下,它指向堆,在第二種情況下,它指向不在堆中的字符串文字。 – paxdiablo 2013-04-24 03:57:01

+0

分配內存的函數或模塊應釋放它;將東西傳遞給別人以釋放是一種很好的泄漏內存或雙倍空閒的方式。但最重要的是確定並記錄所有權語義。當然,如果放棄過時的語言C,可以安全地傳遞所有權,就像使用C++ 11的unique_ptr一樣。 – 2013-04-24 03:59:02