2012-11-04 39 views
4

我想知道處理內存泄漏的協議,指針指向在C和C++中返回的動態內存。例如,strtok返回一個char *。據推測,返回的指針最終必須被釋放/刪除。我注意到reference page甚至沒有提到這一點。那是因爲這是簡單的假設?另外,你如何知道是刪除還是免費?是否需要進行研究以確定每個函數原來的語言,然後假設所有C程序都使用malloc/free,C++使用new/delete?如何處理指向在C/C++中返回的動態內存的指針

+1

參考頁沒有提及它的原因是它不是真的。 –

+0

我認爲重要的是要注意「參考頁面」只是* a *參考頁面,而不是函數的標準定義。但在這種情況下,這是正確的。 –

回答

7

strtok不返回指向新分配的內存的指針,而是返回先前分配的內存位置的指針。

假設這樣的:

char String[1024]; 
strcpy(String, "This is a string"); 
char *Ptr = strtok(String, " "); 

PTR不會指向一個新分配的內存位置,而是以字符串的位置(如果我的計數不會失敗我現在),與空間越來越取而代之的是'\ 0'。 (

從參考: 令牌的這一端會自動通過功能的空字符替換,並且令牌的開頭部分是由函數返回

這也意味着,如果你。在strtok完成其工作後再次打印'String',它將只包含'This',因爲字符串在此之後終止。

作爲一個經驗法則,您可以安全地說,需要釋放/刪除自己明確分配的內存。

表示:

對於每個'新'放一個'刪除',併爲每個'malloc'放一個'免費',你很好。

+2

爲了擴展這一點,在庫函數需要釋放內存的地方,他們會在他們的文檔中告訴你,以及它們是C還是C++函數是否需要'delete'或'free'的關鍵。 –

+1

@LightnessRacesinOrbit是的,當然你是對的。如果明確指出,釋放有關的內存當然是必要的。雖然通常這不是用delete/free做的,而是一個專門的'free'函數,它與'施工調用'相匹配。 – ATaylor

+0

是的,也可以是這種情況,當然在標準C庫以外的庫中。 –

2

strtok是一個C函數,它返回一個指向前一個分配的內存的指針; strtok本身不分配新的內存。

如果用malloc分配了某些內容,則必須將其與free一起分配;任何分配新的項目必須是free d與delete

在現代C++中處理內存分配/釋放的最佳方式是使用智能指針。看看std::shared_ptr/std::unique_ptr,除非你絕對必須使用原始指針。

也使用std::stringstd::vector將刪除大部分原始指針。

1

strtok函數不執行任何內存分配。它正在對您提供的字符串指針執行操作。在函數被調用的時候,你應該已經考慮過是否爲堆上的指針分配內存,還是使用自動堆棧存儲。你可以這樣寫:

char * p = "Testing - string"; 
char * p2 = strtok(p, "- "); 

這裏p2不必蜜蜂被釋放/刪除,因爲它被分配在堆棧上。但這裏

char * p = "Testing - stringh"; 
char * p2 = malloc(strlen(p)); 
p2 = strtok(p, "- "); 

您已經分配儲存在堆上P2,所以你已經完成了它後,它已被釋放,並設置爲null:

if(p2 != NULL) { 
    free(p2); 
    p2 = NULL; 
} 

所以,如果你有使用新的堆分配,然後使用delete;如果你使用malloc/calloc,你應該免費使用。

+0

你知道,你的答案引發了一個有趣的問題。從技術上講,你在程序代碼中使用字符串。 (因爲'p'沒有以任何方式分配)。通常,這些是'const char',這意味着它們不能被改變。我也相信,如果你在這個函數上調用了strtok,你可能會讓你的程序崩潰或出現分段錯誤。你的第二個例子會給你留下內存泄漏(因爲你將覆蓋指向已分配內存的指針),最後一個將會崩潰,因爲沒有內存被分配給'p'。 – ATaylor

+0

對不起,我的意思是免費p2。釋放不是堆分配的p會導致未定義的行爲。謝謝你指出我的錯誤。 – akhilless