用C

2012-10-06 23 views
1

Possible Duplicate:
Difference between char *str=「STRING」 and char str[] = 「STRING」?用C

初始化字符串我寫了下面的代碼:

int main() 
{ 
    char *str = "hello"; 
    str[0] = 'H'; 
    printf("%s\n", str); 
} 

這給了我一個分段錯誤,我無法理解這是爲什麼。

strpointer to char不是const char。即使是這樣的情況下,不應該把它給一個編譯錯誤,像下面的程序:

int main() 
{ 
    const char *str = "hello"; 
    str[0] = 'H'; 
    printf("%s\n", str);  
} 

它給出了一個錯誤:assignment of read-only location *str

編輯

如果我的代碼放置指向一個只讀的位置,我不應該得到一個編譯錯誤?

+0

請使用搜索功能。如果你搜索,你會發現數百個完全相同的問題。 – Marlon

+0

@Marlon請將重複問題的鏈接粘貼到計算器上 –

+0

指針不是隻讀的。它只是指出你的字符串存儲在內存中的位置。在聲明字符串的方式之間存在細微的差別,這會改變它的存儲方式。 –

回答

5

您將一個指針指向一個常量字符串(它作爲文本的一部分,因此不是可寫內存)。

修復char str[] = "hello";這將在您的堆棧上創建一個常量字符串的r/w副本。

你所做的是完全有效的指針分配。編譯器不知道的是,在標準系統中,常量字符串被放置在只讀存儲器中。在嵌入式(或其他奇怪的)系統上,這可能會有所不同。

根據您的系統,您可能會附帶一個mprotect並將指針目標上的VM標誌更改爲可寫。所以編譯器允許這個代碼,你的操作系統不會。

+1

字符串文字不是'const'也不是常量。它是一個標準的'char'數組,它足夠容納所有的字符加上不可寫入的終止符,而不受Undefined Behavior的懲罰。 – pmg

2

當您使用文字字符串初始化char *時,則不應嘗試修改其內容:變量指向不屬於您的內存。

可以使用:

char str[] = "hello"; 
str[0] = 'H'; 

有了這個代碼,您已經聲明這是與文本字符串的內容的副本初始化數組,現在你可以修改陣列。

0

你的代碼在運行時有未定義的行爲。您正在嘗試寫入不允許的文字字符串。這種寫入可能會觸發錯誤或具有未定義的行爲。您的特定C編譯器將str指向只讀內存,並嘗試寫入該內存會導致分段錯誤。即使它不是const,寫入仍然是不允許的。

0
char *str = "hello"; 

當聲明str如上述,它不能保證它會被存儲,其中存儲部。根據實現,str可能是隻讀的。所以試圖改變它會導致分段錯誤。

爲了避免分割faullt,請將str聲明爲字符數組。

0
char *str = "hello"; 

這裏字符串hello是一個文字。 字符串文字總是存儲在只讀存儲器中。 這是您在嘗試更改只讀存儲器中的值時出現分段錯誤的原因。

+0

字符串文字存儲在實現希望存儲的地方,不一定是隻讀的。 – Marlon

+0

在絕大多數情況下,它們都存儲在只讀存儲器中。 –

0

將str聲明爲char *爲指針保留內存,但不爲字符串保留內存。 編譯器可以將「hello」的內存放在任何他喜歡的地方。 你不能保證str [i]是可寫的,所以這就是爲什麼在一些編譯器中這會導致seg錯誤。

如果你想確保字符串在可寫存儲器,那麼你必須使用ALLOC()來分配內存,也可以使用

char str[] = "hello"; 
+0

對不起,我沒有得到爲什麼編譯器不能把內存的「你好」,無論他喜歡 –