2017-06-22 103 views
-1

每當遇到處理c字符串的情況,我都很困惑。C++語言中字符串重複的混淆

爲什麼這兩個打印有相同的結果? 在我的說明中,第一個函數將字符串的地址賦給文本變量。這對我來說似乎是適當的。但第二個函數在文本變量指向的地方分配地址。這裏發生了什麼?

#include <iostream> 
#include <cstring> 

void getText(char** text) { 
    *text = strdup("AAAAA"); 
} 
void getText2(char* text) { 
    text = strdup("AAAAA"); 
} 

int main() 
{ 
    char* text; 

    getText(&text); 
    std::cout << text << std::endl; // prints "AAAAA" 

    getText2(text); 
    std::cout << text << std::endl; // prints "AAAAA" 
} 
+0

這不是C ..應該先清除這個混淆。 –

+0

只要不在C++中使用C字符串,就永遠不會有問題。 –

+1

第二個函數不會修改'main'的'char * text' – UnholySheep

回答

1

此功能

void getText2(char* text) { 
    text = strdup("AAAAA"); 
} 

有內存泄漏。

函數參數是函數局部變量。

你可以想象函數getText2的定義和它的調用方式如下。我重命名了函數參數,它會更清晰。

getText2(text); 

//... 

void getText2(/*char* parm_text */) { 
    char *parm_text = text; 
    parm_text = strdup("AAAAA"); 
} 

局部變量是參數parm_text將在退出功能之後被破壞。然而,在這份聲明中分配的內存

parm_text = strdup("AAAAA"); 

未被釋放。

另一方面,論證本身沒有改變。該函數使用存儲在分配給本地變量的參數中的值。

您可以聲明參數作爲參數的引用。例如

void getText2(char* &text) { 
        ^^^^^ 
    text = strdup("AAAAA"); 
} 

在這種情況下,它是參數本身在函數中被更改。

至於函數

void getText(char** text) { 
    *text = strdup("AAAAA"); 
} 

然後該參數是通過使用一個指針參數間接傳遞。所以在函數內部,參數的值被改變了。

+0

謝謝vlad。關於內存泄漏的意見非常有用。 – positoy

1

在第一種情況下,你傳遞一個指針到本地的指針,取消引用該指針,使之指向由strdup(),正在修改的地址原來的指針指向返回的值。

在第二個中,你通過poiner本身,你不能在函數內改變它,因爲即使兩個指針最初指向相同的內存,它們被存儲在不同的地方,所以改變了一個地址,不會影響其他。

如果你改變了數據的指針指向,而不是在getText2()地址然後它會改變,像

text[0] = 'B'; 
text[1] = 'B'; 
text[2] = 'B'; 
text[3] = 'B'; 
text[4] = 'B'; 

你也應該叫free()您使用返回的指針後strdup()或將是內存泄漏。

最後,在C++中使用指針被認爲是不好的做法,除非你是一個庫程序員,我不認爲是這種情況。相反,使用std::string和所有的C++概念(,如傳遞參考文件中不存在的c)可以讓你編寫現代的C++程序。

通過在C引用傳遞++可能

void getText(std::string &text) 
{ 
    text = "AAAAAA"; 
} 

void getText2(std::string &text) 
{ 
    text = "BBBBBB"; 
} 

int main() 
{ 
    std::string text; 
    getText(text); 
    std::cout << text << std::endl; 
    getText2(text); 
    std::cout << text << std::endl; 
    return 0; 
} 

你去那裏,沒有內存泄漏,它按預期工作,這是現代C++。

+0

爲了使它成爲「真正的」C++,它應該是'std :: string getText()' – Slava