1. 程式人生 > >簡單的問題:char指標無法賦值

簡單的問題:char指標無法賦值

一個簡單的問題:

char* str = "resource";    
str[6] = 'k';  //這句報記憶體寫入錯誤   
*(str+6) = 'k'; //這樣寫同樣報錯   
但是這樣就沒問題:   
char* str = new char[12];   
strcpy(str, "resource"); 
str[6] = k; //沒問題   
*(str+6) = 'k'; //沒問題

這樣也沒問題:

char str[] = "resource";
str[6] = 'k';
*(str+6) = 'k';

從網上搜尋資料後,找到了一個比較準確的解答:   "resource"是字串常量。   對於 char *str = "resource";    把"resource"的值----也就是字串常量字面值,也就是"resource"的地址,準確來說是起始地址----賦給字元指標 str,Linux下,"resource"字串常量是存放於只讀資料區的,一般來說,32位機器上,在Linux中,堆,全域性資料,常量等都是存放於從0x8048000開始的記憶體地址,向上增長。可以列印一下"resource"的地址來進行驗證。char *str = "resource",就是把"resource"的首地址賦給str,所以str 存放的是一個只讀資料區的地址,對只讀區的資料進行寫操作是禁止,具體由相應的作業系統進行判斷以及處理。   

而對於 char str[] = "resource";    str[]是一個字元陣列,編譯器首先在棧中分配一定的連續空間用於存放“resource”中的字元以及結尾符,然後把字串常量的內容,也就是"resource"中的各個字元和結尾符複製到這個棧中的連續空間中。str是陣列名,用來表示這個連續棧空間的起始地址,所以str中存放的是棧地址,這個地址的資料是可寫的。一般來說,32位機器上,在Linux中,棧地址空間從3G(0xbfffffff)開始向下增長。

可以用語句printf("%x\n", str)來打印出str中存放的地址,來驗證一下這個地址屬於棧還是屬於只讀資料區。