2010-11-19 72 views
4

比方說,返回的字符串是這樣寫C/C++字符指針崩潰

char *Function1() 
{ 
return 「Some text」; 
} 

一個固定的「隨機文本」功能,則程序可能崩潰,如果不小心改變做價值

Function1()[1]=’a’; 

函數調用嘗試這樣做會導致程序崩潰後,方括號是什麼?如果您熟悉這一點,任何解釋將不勝感激!

+1

[1]指向字符串中的第二個字符([0]將是第一個字符) – climbage 2010-11-19 16:10:07

+0

爲什麼在標題中說C++,但標記問題C? – GManNickG 2010-11-19 17:03:10

+1

你應該把這個標記爲MSVC,因爲gcc(至少> = 4)會警告你將一個char const []賦值給一個char *已被廢棄......出於充分理由,如你所見。 – mmmmmmmm 2010-11-19 17:54:56

回答

12

您在函數中返回的字符串通常存儲在進程的只讀部分中。試圖修改它將導致訪問衝突。 (編輯:嚴格地說,這是未定義的行爲,並且在某些系統中它會導致訪問衝突。謝謝,約翰)。

這種情況通常是因爲字符串本身是與應用程序的代碼一起硬編碼的。加載時,指針被建立以指向您的進程中只保留文字字符串的只讀部分。實際上,每當你在C中寫入一些字符串時,它將被視爲const char*(指向常量內存的指針)。

+4

你不能說它會導致訪問衝突。 C++不知道有關訪問衝突的信息。你所能說的只是它會引起未定義的行爲 – 2010-11-19 16:23:14

+1

@John:你說得對。以哲學含義爲準:) – 2010-11-19 16:27:24

+0

@John:也許「will」太串了,但你很有可能會這樣做:-) – mmmmmmmm 2010-11-19 17:56:35

0

這不是括號,而是分配。你的函數不是簡單的char *,而是const char *(我在這裏可能是錯誤的,但是這裏的內存是隻讀的),所以你試圖改變不可更改的內存。和括號 - 他們只是讓你訪問數組的元素。

1

你可以使用靜態字符串作爲返回值,但你永遠不會使用它。這就像訪問違規錯誤。它的行爲沒有在C++ Standard中定義。

+0

當然你可以*使用*它。你不能修改它的內容。 – 2010-11-19 16:18:30

+0

ohya,正好。還有一件事(就像工作...... :),就像許多其他人已經說過的那樣,將常量字符串轉換爲非常量字符串是等等等等......你知道〜 – 2010-11-19 16:26:12

4

該功能的簽名應該確實是constchar* Function();

+0

完全同意。 – 2010-11-19 16:15:29

+1

它實際上應該是'std :: string',因爲OP想要修改從函數返回的值 – 2010-11-19 16:23:54

+0

是的,John,在C++中 - 當然,在C中 - 這是唯一的方法。 – 2010-11-19 17:02:37

3

您正在嘗試修改字符串文字。根據標準,這引起了undefined behavior。還有一件事要記住(相關)是字符串文字總是const char*類型。將指針轉換爲字符串文字有一個特殊情況,即char*,刪除const限定符,但底層字符串是仍然是const。所以通過做你正在做的事情,你試圖修改一個const。這也喚起不確定的行爲,並且是類似於試圖做到這一點:

const char* val = "hello"; 
char* modifyable_val = const_cast<char*>(val); 
modifyable_val[1] = 'n'; // this evokes UB 

,而不是從你的函數返回一個const char*的,按值返回string。這將構建一個基於字符串新string文字,並調用代碼可以爲所欲爲:

#include <string> 

std::string Function1() 
{ 
return 「Some text」; 
} 

...以後:

std::string s = Function1(); 
s[1] = 'a'; 

現在,如果你正在試圖改變值Function() reuturns,那麼你將不得不做其他事情。我會使用一個類:

#include <string> 
class MyGizmo 
{ 
public: 
    std::string str_; 
    MyGizmo() : str_("Some text") {}; 
}; 

int main() 
{ 
    MyGizmo gizmo; 
    gizmo.str_[1] = 'n'; 
} 
0

還要注意的是,你可以通過將文本規則陣列避免碰撞:

char Function1Str[] = "Some text"; 

char *Function1() 
{ 
    return Function1Str; 
} 
0

的問題表明,你不明白的字符串文字。

圖像驗證碼

char* pch = "Here is some text"; 
char* pch2 = "some text"; 
char* pch3 = "Here is"; 

現在,編譯器如何分配內存的字符串完全是編譯器的問題。內存可能是這樣組織的:

Here is<NULL>Here is some text<NULL> 

pch2指向pch字符串內的內存位置。

這裏的關鍵是理解記憶。使用標準模板庫(stl)將是一種很好的做法,但是對於您而言,您可能是一個相當陡峭的學習曲線。