2009-12-27 63 views
3

可能重複:
Why does simple C code receive segmentation fault?字符串操作用C問題

嘿大家,我敢肯定,這是一個非常基本的問題,但顯然我在這裏我不是很瞭解的東西。

在冬假期間,我一直在C玩弄很多東西,只是遇到了一些我認爲會工作的東西,但給我一個分段錯誤。

如果我聲明一個字符串爲: char name [5] =「Mike」; 我可以操縱字符串:*(name + 1)='a';這工作正常,名稱變成「Make」。

如果我聲明爲: char * name =「Mike」; 然後嘗試相同的操作:*(name + 1)='a';我遇到了分段錯誤。爲什麼我不能那樣做?如果我malloc空間的字符串:char * name =(char *)malloc(5 * sizeof(char));然後將該字符串複製到名稱:strcpy(name,「Mike」);我可以像上面那樣操縱它。 *(name + 1)='a';作品。 (char *)malloc(5 * sizeof(char)); char * name =「Mike」'和char * name =(char *)malloc(5 * sizeof(char))之間有什麼不同?的strcpy(姓名, 「邁克」);?他們是不是都只是指向包含字符串的內存?

不好意思的問題!

+1

同樣的問題已經被問過很多次,例如http://stackoverflow.com/questions/164194 – ephemient

回答

10

char name[5] = "Mike"聲明一個本地數組並將字符串「Mike」複製到其中。 char* name = "Mike"將指針指向「Mike」而不進行復制。在這兩種情況下,「Mike」都是一個保持在只讀頁面的常量字符串,所以在第二種情況下,您試圖修改原始常量。

+1

豈不編譯器標誌(至少有一個警告)因爲「Mike」在技術上是一個「const char *」,所以'char * name =「Mike」'是因爲丟棄了「Mike」的const屬性?或者C不在乎丟棄'const'? –

+0

@Mike:沒有邏輯。出於兼容性的原因,這只是一箇舊的疣。 –

1

當你聲明一個字符數組時,內存被分配到堆棧上,你可以寫入它。

當您稍後調用malloc()時,您會在堆中分配內存,並且可以寫入該內存。

當你在中間發生崩潰的事情時,你已經聲明瞭一個指向生活在內存中的字符串的指針,你不能改變它。它是靜態的,只讀的。

2

到目前爲止,大家都說過了,但我不確定它是否足夠清楚。

char array[5] = "Mike" 

創建一個常數字符串「邁克」,分配大小5的堆棧上的陣列,並複製常量字符串到它(理論上...編譯器將可能優化步驟出來)

char *array = "Mike" 

創建相同的常量字符串「邁克」,但只是分配指針,而不是將其複製到本地堆棧。

「常量字符串」,它可能是一個字符串分配在內存中,並由操作系統標記爲只讀,所以您嘗試修改它會導致分段錯誤。

+0

這很有道理,謝謝! – itscaleb

2

您試圖修改文本字符串,其調用未定義行爲

char *array="Mike"; /* String Literal is stored in read only section of memory */ 

*array='P'; /* Undefined Behavior */ 

C99第6.4.5.6(Section--字符串)中明確規定:

這是unspeci網絡版這些陣列是否只要它們的要素具有適當的價值就是明確的。如果程序試圖修改這樣一個數組,的行爲是undefined

然而,

char array[5] = "Mike";/*Creates a local array and copies the string "Mike" into it*/ 

*array='P';/*Fine*/