2013-01-24 37 views
2

我讀這在維基百科爲什麼Segmentation在下面的代碼中出錯?

int main(void) 
{ 

    char *s = "hello world"; 
    *s = 'H'; 

} 

當被編譯包含該代碼的程序,所述字符串「Hello World」被放置在程序可執行文件的部分被標記爲只讀的;加載時,操作系統將其他字符串和常量數據放在只讀內存段中。執行時,變量s被設置爲指向字符串的位置,並嘗試通過變量將H字符寫入內存,從而導致分段錯誤**我不知道爲什麼該字符串被放置在只讀段中。有人可以解釋這一點。

+0

可能重複的[C:指針和數組之間的差異](http://stackoverflow.com/questions/1335786/c-differences-between-pointer-and-array) –

回答

3

字符串文字存儲在只讀存儲器中,這就是它的工作原理。您的代碼使用初始化的指針指向存儲字符串文字的內存,因此您無法有效修改該內存。

要獲得修改內存中的字符串,這樣做:

char s[] = "hello world"; 

那麼你很好,因爲現在你僅僅使用常量字符串初始化非常量數組。

+1

要迂腐,他們沒有輸入'const char *'... –

+0

@OliCharlesworth Doh。我應該知道這太簡單了。重寫了,謝謝。 – unwind

+0

@unwind如果字符串文字是'const char *',那麼就不會有* question:代碼就不會編譯(這就是爲什麼我downvoted的原因 - 而且我會在更正它的時候刪除downvote)。也就是說,在迄今爲止的所有答案中,沒有試圖解釋將字符串文字移動到只讀部分的目的。 (目前還不清楚問題是要求達到目的還是「這只是如何運作」就足夠了)。 –

2
  • 當你這樣做:char *s = "hello world";然後s指向內存是在代碼部分指針,所以你不能改變它。

  • 當你這樣做:char s[] = "Hello World";然後s屬於堆棧上字符 數組,這樣你就可以改變它。

如果您不想在程序期間更改字符串,最好是:char const *s = ....;。然後,當您嘗試更改字符串時,程序不會因分段錯誤而崩潰,則會出現編譯器錯誤(這會更好)。

3

有一個很大的區別:

char * s = "Hello world"; 

char s[] = "Hello world"; 

在第一種情況下,s是一個指針的東西,你不能改變。它存儲在只讀存儲器中(通常位於應用程序的代碼部分)。

在後一種情況下,您在讀寫內存(通常是普通RAM)中分配一個數組,您可以修改它。

+1

在第一種情況下,我也希望編譯器發出關於將const分配給非const或其他東西的警告。 – junix

0

先有三分球有很好的理解,我將要給你一個簡短的演示:

首先,讓我們通過線分析你的代碼行。讓我們從主開始

char * s =「Some_string」;

首先,您正在聲明一個指向char變量的指針,現在* s是內存中的一個地址,如果您嘗試更改其內存值,那麼C將會踢你,這是非法的,所以你最好聲明一個字符數組,然後將s分配給它的地址,然後改變s。

希望你得到它。有關進一步的參考和詳細的理解,請參閱KN King:C編程現代方法

0

根據語言定義,字符串文字必須以這樣的方式存儲,即它們的生命週期在程序的整個生命週期中延伸,並且它們是在整個程序中可見。

這究竟意味着什麼其中字符串被存儲爲直到實施;語言定義並不要求字符串文字存儲在只讀存儲器中,並不是所有的實現都這樣做。它只是說試圖修改字符串文字的內容會導致未定義的行爲,這意味着實現可以自由地執行任何想要的操作。

相關問題