?? 常量、指向常量的指針,常量與變量的區(qū)別.txt
字號:
我在VC中編程時(shí),寫了這樣兩句代碼。
char * q = "Hello";
*q = 'W';
編譯沒有錯(cuò)誤。當(dāng)運(yùn)行到第二句時(shí),總會提示這樣的錯(cuò)誤:
Unhandled exception in GeneralTest.ext: 0xC0000005: Access Violation.
請問這是為何?
按理講,我只是通過指針更改其所指內(nèi)存中的指而以,怎么會出錯(cuò)呢?怎么又總是在0xC0000005處出錯(cuò)呢?
--------------------------------------------------------------------------------------------
我在此將各位前輩對此問題的解答進(jìn)行系統(tǒng)的整理。
此問題代碼中,"Hello"是一個(gè)常量,由于c/c++定義中常量是不能被修改的。所以盡管飛翔將存儲常量的地址賦給了一個(gè)指針,指針可以獲得這個(gè)常量的值,但是對它進(jìn)行修改卻是非法的。
根據(jù)c/c++語法,當(dāng)你聲明該量為常量,即告訴程序和編譯器,你不希望此量被修改。
程序的實(shí)現(xiàn),為了保護(hù)常量,特將常量都放在受保護(hù)的靜態(tài)存儲區(qū)內(nèi)。凡是試圖修改這個(gè)區(qū)域內(nèi)的值,都將被視為非法,并報(bào)錯(cuò)。
這不能理解為凡是字符串都是放在靜態(tài)存儲區(qū)域的。這個(gè)跟數(shù)據(jù)類型沒有關(guān)系,而是這個(gè)量是變量還是常量的問題。例如,一個(gè)字符串變量就是可以被修改的。
這種靜態(tài)存儲區(qū)域的保護(hù)機(jī)制是由編譯器實(shí)現(xiàn)的,而非存儲該值的內(nèi)存的電器屬性。換言之,實(shí)質(zhì)上內(nèi)存永遠(yuǎn)都可以被用戶隨意修改,只是編譯器給用戶的代碼注入了一些自己的保護(hù)代碼,通過軟件手段將這段內(nèi)存軟保護(hù)起來。這種保護(hù)在匯編級別可以輕松突破,其保護(hù)也就無效了。
vc6的debug模式編譯結(jié)果給程序添加了這樣的保護(hù),幫助用戶盡早發(fā)現(xiàn)程序錯(cuò)誤,而非此保護(hù)不可或缺。而release模式下對程序針對運(yùn)行效率進(jìn)行了優(yōu)化,這樣的保護(hù)顯然是要消耗系統(tǒng)資源的,不利于提高效率。而且編譯器假定,一個(gè)要發(fā)布的想要在release模式下編譯的程序必然經(jīng)過了debug模式的調(diào)試,已經(jīng)處理了這樣的錯(cuò)誤。所以此時(shí)在審查就是冗余的了,vc6的release模式下放棄了對常量的保護(hù)。因此如果你的代碼沒有經(jīng)過debug模式的編譯而直接release,就沒有人去檢查你是否修改了常量,也沒有人去禁止這個(gè)操作。
這并非說release模式下承認(rèn)對常量修改的合法性,僅僅是不去管理罷了。vc6的release模式下放棄了對常量的保護(hù),但是其他的實(shí)現(xiàn)未必這樣做,這要具體看你的實(shí)現(xiàn)環(huán)境了。
從本質(zhì)上說,對于機(jī)器,對于硬件是不存在常量與變量的區(qū)別的。它們都是內(nèi)存中被分配了的一段內(nèi)存空間罷了。甚至不存在數(shù)據(jù)類型上的區(qū)別。對所有的數(shù)據(jù)來說,內(nèi)存都是一樣的。數(shù)據(jù)之間的相互區(qū)別也是通過存在內(nèi)存中的數(shù)據(jù)實(shí)現(xiàn)的。
對于這方面,學(xué)習(xí)過匯編的朋友會比較清楚。
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -