C++中char[]能修改char*卻不行
少扯淡沒用的,直接上代碼
int main(int argc, char *argv[]) { char p[74] = "abcefghijkmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm"; char *a = "abcefghijkmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm"; printf("%s,%s",p,a); }
這誰都能看明白,最終輸出兩次abcefghijkmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm,沒問題
把代碼再改改
int main(int argc, char *argv[]) { char p[74] = "abcefghijkmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm"; char *a = "abcefghijkmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm"; p[8]= 'd'; a[8] = 'd'; //printf("%s,%s",p,a); }
運行,報錯
錯誤指向瞭a[8] = ‘d’
錯誤指向第12行,為嘛尼?
看匯編
可以看到變量p,和a 都是采用瞭同樣的方式
d使用瞭
mov esi,offset string "abcefghijkmmmmmmmmmmmmmmmmmmmmmm"...
將字符串的偏移地址,賦值到esi寄存器
a使用瞭
mov dword ptr [a],offset string "abcefghijkmmmmmmmmmmmmmmmmmmmmmm"...
將字符串的偏移地址,賦值到a變量所在地址
仔細看圖 這兩句對字符串的取址操作,來源都是一個地方,01007500h,也就是程序數據段在內存中的位置
既然兩個操作都是對同一個字符串的操作,為什麼有的可以修改,有的不行?
這裡面有個關於編譯文件後程序的存儲問題,如上例
變量a,p他們都是操作相同的字符串,兩個字符串完全相同,所以,程序編譯後,生成的文件內,完全沒有必要保存兩個相同的內容,隻保留一個便可以,所以,你的程序,不管多少次使用這個字符串,實際上都是從一個地方引用的,這就是,這兩句代碼
mov esi,offset string "abcefghijkmmmmmmmmmmmmmmmmmmmmmm"... mov dword ptr [a],offset string "abcefghijkmmmmmmmmmmmmmmmmmmmmmm"...
的意思。
但這就出現瞭一個問題,如果兩個或者多個變量都用瞭同一個字符串,然後最終要的,還進行瞭修改,結果就是,所有引用這個字符串的變量,都變瞭,所以
a[8] = 'd';
要直接修改數據段,就報錯瞭
但是p可以,為什麼,應為數組的處理是不一樣的,看代碼
mov esi,offset string "abcefghijkmmmmmmmmmmmmmmmmmmmmmm"... (0977588h) lea edi,[p] rep movs dword ptr es:[edi],dword ptr [esi]
首先,把字符串的地址給瞭esi,然後把p地址給瞭edi,
然後,通過rep movs 循環執行,吧[esi]處的字符,賦值給[edi],也就是把字符串復制一份到p
所以,你操作的
p[8] ='d';
實事上是操作瞭一個新的字符串,不是數據段中的那個字符串,
再看關於a的操作
mov dword ptr [a],offset string "abcefghijkmmmmmmmmmmmmmmmmmmmmmm"... mov eax,1 shl eax,3 mov ecx,dword ptr [a] mov byte ptr [ecx+eax],64h
首先把1給瞭eax,然後執行位移3,把EAX,變成8,把a的地址,也就是字符串的地址給瞭ecx,然後吧64h也就是d,賦值給[ecx+eax] 那個位置,也就是j的位置,因而你操作的是數據段中的那個字符串,就是上面的原因,系統會阻止你修改數據段,因而報錯
到此這篇關於C++中char[]能修改char*卻不行的文章就介紹到這瞭,更多相關C++ char*不能修改內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!