2011-04-11 81 views
1

我試圖追捕內存泄漏,並找到一個來源。我是一個函數中的指針,並將它釋放到另一個函數中,但我錯過了解如何複製指針指向的值,同時也能夠釋放指針。複製和釋放malloc'ed指針

Current implementation (with memory leak): 

// This code has been greatly simplified 
// and as such does not appear to have any purpose 
int foo(){ 
    int bestval = 0; 
    char *best; 
    char *match; 
    for (int i=0;i<3;i++) { 
     int returnValue = bar(&best); 
     if (returnValue > 10) { 
     (1) 
     match = best; 
     } 
    } 

    printf("%s", match); 
    (2)  
    return 0; 
} 


int bar(char ** best) { 
    char*s = "Hello!"; 
    *best = malloc(strlen(s) + 1); 
    strcpy(*best,s); 
    return 0; 
} 

兩個問題

  1. 如果我有空閒內存在,而不是(2),我會怎麼做,所以那場比賽仍然會是什麼載於最好的(1) ?

  2. 我應該做strcpy複製最佳匹配?如果是這樣,我是否必須在foo內做另一個malloc?

+0

假設有一個自由點二,你發佈的代碼不漏,但後「 2',這個點之後匹配無效......你是否在循環中運行這段代碼? – forsvarir 2011-04-11 07:23:32

+0

爲什麼你需要2個「最好」和「匹配」指針? (2)你可以簡單地使用'best'和'free'。 – Naveen 2011-04-11 07:23:57

+0

@forsvarir,是的,我在一個循環中運行它,這就是爲什麼我在(1)處實現免費的原因。 – Rio 2011-04-11 07:26:26

回答

1

在黑暗中刺了一下,假設有Foo中環...

int foo() 
{ 
    int bestval = 0; 
    char *best; 
    char *match = 0; // initialize to null 

    // start some loop 
    for (int i=0;i<3;i++) {  

     // fetch the next best value... 
     int returnValue = bar(&best);  
     // some check (if best is really best!) 
     if (returnValue > 10) { 
      // if match has previously been populated, free it 
      if(match) { 
       free(match); 
      } 
      // save the new best value 
      match = best; 
     } 
     else { 
      // not saving best in match, so free it! 
      free(best); 
     } 
    } 
    // end some loop 

    // only do this if match was successful?!? 
    if(match) { 
     printf("%s", match);  
     // clean up once the best of the best has been used... 
     free(match); 
    } 
    return 0; 
} 
+0

我喜歡這個,這很有道理。我會嘗試一下,並將結果報告給您! – Rio 2011-04-11 07:45:40

+0

@Rio:我剛剛添加了另一個免費的...如果你不保存最好的匹配,你需要確保你釋放它... – forsvarir 2011-04-11 07:46:11

+0

最後一件事是緊緊的! – Rio 2011-04-11 07:53:55

0

您需要知道字符串的大小。
在(1)您將分配已經釋放的內存地址的地址,如果您想釋放最佳空間,則必須對另一個malloc執行match*=malloc(sizestr)然後將其複製爲memmove或strcpy。

如果我理解正確,你想複製到最好的字符串,然後釋放最好的內存和分配ptr匹配?如果在移動或strcpying到另一個位置之前釋放最佳內存,則會丟失其內容,並且如果您想先將其複製到另一個位置,則需要分配要將其複製到的內存,因此您需要在該代碼上使用2個malloc 。

0

如果我不得不在(1)而不是(2)處釋放記憶,我該怎麼做才能讓匹配仍然具有最好的內容?

如果free(1)位置,這是不可能做到這一點,使match仍然會有什麼載於best

我應該做strcpy來複制最佳匹配嗎?如果是這樣,我是否必須在foo內做另一個malloc?

match = best; 

上面的說法,兩者都指向同一個位置。所以,根本不需要strcpy。爲此,請爲match分配內存以指向其長度爲best+1,然後執行strcpy

0

複製指針的值不會複製底層內存。因此,不要free(best),直到你完成match,或者你需要malloc一個新的緩衝區,例如, memcpy()從一個緩衝區到另一個緩衝區的內容。

1

在功能欄中的strcpy應爲

strcpy(*best,s); 

在主函數中,你可以通過

strcpy(match, best); 
free(best); 

比賽之前需要指向一個有效的內存塊的價值最好的點複製到。如果你做一個

match = best; 
free(best); 

匹配將是無效的,因爲它指向相同的釋放最好的指針。

+0

'delete'是C++的,需要'free()'在這裏... – 2011-04-11 07:29:00

+0

你'關於strcpy。我修正了這個問題。 – Rio 2011-04-11 07:29:41

+0

對不起,仍然有點用C++ ;-)修正。 – hirschhornsalz 2011-04-11 07:31:13

0

是的,你可以mallocstrcpy:如果你不已經

match = strdup(best); 

match = malloc(strlen(best) + 1); 
strcpy(match, best); 

但是,如果你的實現提供了它,你可以使用strdup()功能,更容易有strdup(),最好自己創建一個。

0

您當前的任務只是將指針分配給相同的緩衝區。如果你接着這個緩衝區,你已經刪除了這裏包含的內容(因此解引用它是一個壞主意)。
您無需使用strcpy()複製最佳匹配 - 在printf()(或需要的最後一點)之後,您最好將其釋放。用一個額外的函數調用或六個函數調用過於複雜的東西是沒有意義的,只要記住在每個函數結束時分配的內存。