2009-11-06 58 views
1
char *a() { 
    char *t = malloc(8); 
    t[0] = 'a'; 
    t[1] = 'b'; 
    //... 
    t[7] = 'h'; 
    return t; 
} 

int main(void) { 
    char *x = a(); 
    //do something with x 
    //... 
    free(x); 
    return 0; 
} 

此代碼是否有任何潛在的問題,因爲內存分配在a()和已用內存main()這是否使用C指針可以防止泄漏內存?

回答

0

不,您明確不會有任何問題,因爲您分配了a中的功能並在main中使用它。

1

沒有問題—其實,這是分配函數返回—但你可能要free()內存當你用它完成後,將仍然使用的內存的正確方法。八個字節不會成爲問題,但針對內存泄漏進行編碼是一個很好的習慣。

+1

+1即使你錯過了從void void()中返回值的問題(我也幾乎錯過了,並且@Ed擊敗了我們所有人)。 – 2009-11-06 21:49:08

+0

Ack - 好趕上! – 2009-11-06 21:51:57

0

只要你記得釋放x指向的內存,那麼你將不會有任何問題。通過使用malloc(),您可以在堆回到調用函數時獨立分配內存。

10

首先,a()被聲明爲返回void,但您試圖返回一個char *。更改簽名以返回char *。

其次,你的函數很好,但是你的示例代碼有內存泄漏,因爲你永遠不會釋放返回的指針指向的內存。

第三,正如gbrandt指出的那樣,在調用malloc之後,您沒有檢查成功。 malloc可能會失敗,並檢查它是否成爲一個好習慣。


另一種方式來實現,這將是一個指針傳遞給一個指針變成()來代替,然後調用者有其傳遞到()之前創建的指針本身,但無論哪種方式,你仍然需要釋放內存。說實話,在這種情況下,我會用你的方法來解決這個問題。沒有令人信服的理由這樣做,只是想我會提到它。

void a(char **p) 
{ 
    *p = malloc(8); 
    if (*p) 
    { 
     **p[0] = 'a'; 
     **p[1] = 'b'; 
     ... 
     **p[7] = 'h'; 
    } 
} 

int main(void) 
{ 
    char *x; 
    a(&x); 
    //do something with x 
    ..... 
    free(x); 
} 

如果這種替代方法混淆了你,請讓我知道,我會很樂意提供解釋(雖然,此刻,我要回去工作!)

+1

+ 1爲了讓我從「void」函數返回而獲得勝利,但是,爲什麼不只是'a'返回'char *'?這會容易得多(並且對於像C這樣懷疑OP的人來說,對於新來的人來說可能會更容易混淆)。 – 2009-11-06 21:50:20

+0

是的,我不確定是否應該包括那部分。我編輯帖子說原來的方式沒問題,這是完成同樣任務的另一種方法。 – 2009-11-06 21:52:34

1

除了有a()(應該是char *而不是void)的錯誤返回類型,代碼沒有任何問題。

只要確保將free()分配給內存即可。

3

以上所有的好建議。代碼的小問題,最大的問題是...

您不在malloc中檢查成功或函數調用。不要忘記錯誤處理。

+0

+1,因爲我也忘記了錯誤處理。 – 2009-11-06 21:54:50

+0

實際上*有*代碼的某些問題(錯誤的返回類型),但用於檢查malloc的內存+1。 – Francesco 2009-11-06 21:56:10

+0

+1,因爲我也忘了檢查malloc返回的內容。 – 2009-11-06 22:07:02

1

這裏的大多數答案表明這不是問題,只記得稍後釋放()它。這在技術上是正確的,但確實是一個問題。任何時候你在一個範圍內分配內存,並期望它在另一個範圍內釋放,你就會要求內存泄漏。人們不記得釋放記憶。還有一個問題,調用者必須知道你使用了malloc,而不是alloca()或new()或其他東西。如果他們調用除匹配的解除分配例程之外的其他任何內容,則結果是不確定的。

總而言之,分配內存並將其傳回給調用者通常是一個錯誤。

最好是期望內存由調用者分配,因爲如果他們分配內存,他們會記住釋放內存並正確執行。

+2

這不是OP代碼的問題,它是OP代碼(虛構)用戶的問題。如果你是C程序員,你記得'free()'內存。期。任何不瞭解內存管理的人,不會閱讀關於他們完成「釋放()」所需內存的文檔時不知道C. – 2009-11-06 21:58:47

+1

是的,我同意克里斯。這是C,而不是C++。 – 2009-11-06 22:00:57

+0

@Ed - Ouch。這對C++程序員來說有點苛刻。不是說這不一定是真的... – 2009-11-06 22:07:03

0

謝謝。我剛編輯了代碼。我想這次應該沒有問題。順便說一下,在C中,當函數完成時,編譯器是否清除堆棧中的所有變量(包括指針012)?

+0

如果它是函數中的局部變量,函數返回時它將從堆棧中消失。但是如果你把它分配在堆上(ala malloc()等),儘管指向它的指針會隨着堆棧幀丟失,但是如果你在返回之前沒有釋放()它,分配的內存將會持續存在。當然,在這個例子中,因爲你正在返回一個指向它的指針,所以調用函數可以保持內存的句柄。 – 2009-11-06 23:06:38