2013-07-02 241 views
0
int main(void){ 
    char * strPtr="Hello World"; 
    printf("\n%s", strPtr);  
    *(strPtr+2)='Z'; 
    printf("\n%s", strPtr);  
    getch(); 
} 

我想爲什麼我不能更改數組的第二個元素?

*(strPtr+2)='Z'; 

編譯器來改變字符數組的第二個元素不會給任何錯誤,但是當我執行,代碼掛起計算機。 錯誤在哪裏?

回答

6

轉換代碼,使用一個實際的陣列,而不是一個字符指針:

int main(void){ 
    char strPtr[] = "Hello World"; 
    printf("\n%s", strPtr);  
    *(strPtr+2)='Z'; 
    printf("\n%s", strPtr);  
    getch(); 
} 

,你會沒事的。當您在代碼中使用初始化字符指針時,字符串數據爲「只讀」,這就是您經常無法修改它的原因。像其他任何數組一樣,實際的數組不再是真的。

當然,因爲strPtr現在是一個數組,它應該被重新命名,並使用普通索引的修改比較好寫的,就像這樣:

strPtr[2] = 'Z'; 
13

因爲當你聲明類似

char * strPtr="Hello World"; 

它實際上是一個const char *所以你不能修改它。

你可以改變你的代碼

char * strPtr= strdup("Hello World"); //free it after 

char strPtr[30] = {0}; 
strncpy(strPtr, "Hello World", 11); 

,你的代碼將工作

+0

這可是不錯的,即使有 - 一些編譯器沒有看到需要標記這個隱含的const聲明,並帶有警告 – LostBoy

+0

如果你在linux上使用g ++,即使沒有任何標誌,你也會得到一個警告 – Alexis

+0

我用GCC 4.4.5測試過,它很高興地忽略了這個問題, - 牆...因此,「一些編譯器」) – LostBoy

2

strPtr點staic內存地址,如 「Hello World」 的是部分你的二進制。您正在嘗試更改「Hello World」字符串,這是不允許的。

你可以做

char strPtr[30] = {0}; 
memcpy (str, "hello World",11); 
*(strPtr+2)='Z'; 
2

這是因爲strPtrconst char *。如果您需要更改此數組的元素,你應該給它分配在堆中,就像這樣:

int main(void){ 

    char * strPtr= malloc(sizeof("Hello World") + 1); 
    strncpy(strPtr, "Hello World", sizeof("Hello World") + 1); 
    printf("\n%s", strPtr);  
    *(strPtr+2)='Z'; 
    printf("\n%s", strPtr);  
    getch(); 
    free(strptr); // don't forget to free it ! 
} 
+0

'的strdup()'它不是那麼便攜,POSIX。看到'getch()'函數讓我覺得他在MS Windows上。 :) – yeyo

+0

@Kira哎呀!謝謝,我已經編輯我的答案:) – nouney

+0

哎呀,這是激烈的。感謝您的回答 – Lyrk

1

因爲你宣佈一個const指針,這裏的內存是不是被分配到堆。內存必須被分配到堆,這樣就可以對其進行修改:

char * strPtr="Hello World"; 

使用mallocstrdup由亞歷克西斯

的建議這應該也行:

char strPtr[]= "Hello world"; 
+1

我敢肯定,內存可以在堆棧上修改過。 – 2013-07-02 12:03:06

+0

@Armin是的,而是動態的變量在堆中分配。 – dejavu

+0

我沒有看到你的答案使用動態分配的變量。 – 2013-07-02 16:08:39

相關問題