2010-06-03 25 views
6

好吧previous問題得到了明確回答,但我發現了另一個問題。C++新增&刪除以及字符串和函數

如果我這樣做:

char *test(int ran){ 
    char *ret = new char[ran]; 
    // process... 
    return ret; 
} 

,然後運行它:

for(int i = 0; i < 100000000; i++){ 
    string str = test(rand()%10000000+10000000); 
    // process... 

    // no need to delete str anymore? string destructor does it for me here? 
} 

所以的char *轉換爲字符串後,我不用擔心刪除了嗎?

編輯:作爲回答,我必須delete[]每個new[]電話,但在我的情況下,其不可能的,因爲指針迷路了,所以問題是:我怎麼轉換字符字符串是否正確?

+0

回覆:編輯...或者不要不會丟失指針(按照下面的答案)或(更好的是)不要指向'new',只需使用'std :: string'來保存字符串。你爲什麼想自己做內存分配? – Johnsyweb 2010-06-03 14:06:44

回答

9

在這裏你是不是轉換char*[std::]string,但複製char*[std::]string。根據經驗,每new應該有一個delete

在這種情況下,你需要存儲的指針的副本,並delete它時,你就大功告成了:

char* temp = test(rand()%10000000+10000000); 
string str = temp; 
delete[] temp; 
+0

那麼我如何正確地將char轉換爲字符串? – Newbie 2010-06-03 13:47:30

+0

我猜你什麼時候被告知將char *轉換爲std :: string是什麼意思,你應該使用** std :: string而不是char *'而不是轉換*編程。 – Johnsyweb 2010-06-03 13:51:03

+0

有沒有更簡單的方法可以做到這一點?像某種功能或某種東西,所以它只需要一行代碼? – Newbie 2010-06-03 13:51:16

2

是的,是的,你這樣做。

如果您使用的是Linux/OS X的,看看像valgrind它可以幫助您與內存問題

你可以改變你的測試功能,使其返回string代替char *,這樣你就可以delete [] ret在測試功能中。

或者你也可以在測試中使用一個字符串,而不必擔心新的/刪除。

+0

所以我必須使用:delete [] str; ? – Newbie 2010-06-03 13:44:47

+0

不,str是它自己的對象。在這種情況下,你已經失去了指向你分配的新char []的指針,因此你將無法刪除內存泄漏。 – 2010-06-03 13:46:05

3

你似乎是impresison根據該傳遞char*到的std ::字符串傳輸分配的內存的所有權。實際上它只是做一個副本。

解決這個問題的最簡單方法是在整個函數中使用std :: string並直接返回。

std::string test(int ran){ 
    std::string ret; 
    ret.resize(ran - 1); // If accessing by individual character, or not if using the entire string at once. 
    // process... (omit adding the null terminator) 
    return ret; 
} 
+0

+1用於跳過創建char *的中間步驟。也就是說,您的示例代碼缺少名稱... – 2010-06-04 00:26:53

2

必須呼籲delete,每new否則將導致內存泄漏。如果你已經顯示你扔掉指針,如果你必須離開函數返回char*,那麼你將需要使用兩行來創建std::string,因此你可以保留char*delete的副本。

更好的解決方案是重寫你的test()函數直接返回std::string

2

你需要做這樣的事情:

for(int i = 0; i < 100000000; i++){ 
    int length = rand()%10000000+10000000; 
    char* tmp = test(length); 
    string str(tmp); 
    delete[length] tmp; 
} 

這正確刪除分配的字符數組。順便說一句,如果你以這種方式創建它(例如函數test),你應該總是零終止一個字符串,否則一些函數可能很容易被「混淆」並將字符串作爲其一部分處理,在最好的情況下會崩潰你的應用程序,並在最糟糕的情況下創建一個無聲的緩衝區溢出導致未定義的行爲在稍後的點,這是最終的調試噩夢...;)