2009-10-30 81 views
1

爲什麼當我使用下面的方法,將用於所有字符轉換成字符串爲大寫,不同的字符串初始化會產生不同的行爲?

while (*postcode) { 
    *postcode = toupper(*postcode); 

    postcode++; 
} 

使用下面的參數作品,

char wrong[20]; 
strcpy(wrong, "la1 4yt"); 

但以下,沒有按不,儘管他們是一樣的?

char* wrong = "la1 4yt"; 

我的程序崩潰試圖寫入非法地址(段錯誤,我猜)。這不是malloc ing的問題嗎?不是無效的?它不應該是...

通過調試,我注意到它試圖分配第一個字符作爲其大寫崩潰。

任何幫助表示讚賞!

+1

http://stackoverflow.com/questions/1614723/why-is-this-c-code-causing-a-segmentation-fault/1614739#1614739 – AnT 2009-10-30 00:29:47

+1

+1避免'* postcode = toupper(* postcode ++) ;''或同樣不好的'*郵編++ = toupper(*郵編);':) – pmg 2009-10-30 00:55:31

+1

爲了大聲哭泣......這個問題每週至少會彈出兩次。 – ephemient 2009-10-30 01:03:48

回答

5
char* wrong = "la1 4yt"; 

聲明一個指針,指向一個字符串常量。常量不能被修改,這就是爲什麼你的代碼崩潰。如果你寫的更迂腐

const char* wrong = "la1 4yt"; // Better 

然後編譯器會發現錯誤。只要你聲明一個字符串文字的指針,而不是創建一個數組,你應該可以這樣做。

另一方面,這分配了20個字符的讀/寫存儲空間,因此寫入空間很好。

char wrong[20]; 

如果你想初始化它到上面的字符串,你可以這樣做然後將被允許改變它。

char wrong[20] = "la1 4yt"; // Can be modified 
char wrong[] = "la1 4yt"; // Can be modified; only as large as required 
+0

有沒有辦法只有內存需要保存「la1 4yt」將分配在初始化[可變]字符串?在數組中聲明它對我來說太冗長了。 – 2009-10-30 00:19:19

+0

當然,您可以省略大小並讓編譯器計算它。 – 2009-10-30 00:21:45

2
char * whatever = "some cont string"; 

是隻讀的。

2

在第二個變體中,"la1 4yt"是一個常數,因此處於只讀段。只有指向常量的指針(wrong)是可寫的。這就是爲什麼你得到段錯誤。然而,在第一個例子中,一切都是可寫的。

這一次可能是有趣:http://eli.thegreenplace.net/2009/10/21/are-pointers-and-arrays-equivalent-in-c/

+0

歡呼的鏈接 – 2009-10-30 00:15:51

+0

請參閱http://c-faq.com/aryptr/aryptrequiv.html和http://c-faq.com/aryptr/aryptrparam.html和http://c-faq.com/aryptr /arypbref.html – 2009-10-30 01:19:08

1

當你

char wrong[20] = "la1 4yt"; 

編譯器拷貝字符串的文字{'l', 'a', '1', ' ', '4', 'y', 't', '\0'}wrong陣列的相應元素中的元素;當你做

char *wrong = "la1 4yt"; 

編譯器分配給wrong字符串常量的地址。

字符串文字char[](字符數組),不const char[] ...但你不能改變他們!從標準

報價:

6.4.5 String literals 
6 It is unspecified whether these arrays are distinct provided 
    their elements have the appropriate values. If the program 
    attempts to modify such an array, the behavior is undefined. 

當我使用一個字符串初始化char *,我平時也告訴編譯器我不會改變該字符串的內容文字中加入一個const到定義。

const char *wrong = "la1 4yt"; 

編輯

假設你有

char *test1 = "example test"; 
char *test2 = "test"; 

,編譯器創建1單一字符串字面量和使用的單一字符串文字來初始化TEST1和TEST2。如果你被允許改變字符串字面...

test1[10] = 'x';  /* attempt to change the 's' */ 
printf("%s\n", test2); /* print "text", not "test"! */ 
+0

標準摘錄中的歡呼聲! – 2009-10-30 00:25:25