在C語言中const類型的數據嚴格意義上可以修改:
const int a=1;
int*b=&a;
*b=2;
不同于C語言,C++中指針類型是要嚴格對應的,對const類型的數據必須使用const類型的指針進行接收,從而避免修改;
但問題是c++中同樣支持指針的強制類型轉換那么問題就出現了,對于下面這段代碼輸出就會顯得不正常:
const int a=1;
int*b=(int*)&a;
*b=2;
cout<<a<<" "<<b<<endl;
cout<<&a<<" "<<b;
我們會發現對a和b,它們的值不同但是對應的地址不同,就好像出現了一個地址內包含兩個值的情況。
回顧內存劃分可以發現,const類型的數據一般存儲在data區,而指針類型數據則通常存儲在棧區,實際上不同的分區存儲數據的規則不同,但一般不會出現相同的地址,除非以下兩種情況:
- 內存映射:操作系統在虛擬內存中進行地址映射時,可能將不通過的存儲區域映射到相同的虛擬地址。
- 編譯器優化:編譯器可能會對代碼進行優化,將某些數據放在相鄰的內存地址,包括不同存儲區域的數據。這種優化可能導致棧上的變量和數據區的變量具有相同的地址。
如果說虛擬地址不是全局唯一的話就可以推測是對const強制類型轉換后改變值的行為是未定義的,編譯器進行了優化,在棧區重新開辟了一段地址用于進行修改,所以就出現了兩個不同的變量擁有相同地址的情況。