同事遇到乙個簡單的問題:
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中存放的位址,來驗證一下這個位址屬於棧還是屬於唯讀資料區。
而對於char* str = new char[12];
由於重新分配了記憶體,然後將常量字串內容拷貝過來,這樣str指向的不是唯讀資料區,也就可以修改了。
但是要注意的是,下面的**也是不行的:
char*p或許通過我的這個例子大家可以更容易的理解這個問題,在編譯器除錯狀態下,可以很容易地看到,剛分配完記憶體的p的位址與給p賦值後的位址明顯不同,所以經過後乙個賦值語句後,p又重新指向了唯讀記憶體區,所以又不能修改了!=new
char[12
];p ="
resource";
p[6] =
'k';
//報錯
本文**:
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 resourc...
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...
遍歷字典時不能修改字典的內容
private gtsactor idictionaryconfigs exception 集合已修改 可能無法執行列舉操作。在 system.throwhelper.throwinvalidoperationexception exceptionresource resource 在 system...