2016-08-24 33 views
3

使用指針寫入常量變量會導致運行時錯誤。系統如何知道被訪問的地址是否爲常量

const int i; 
int *p; 
void main() 
{ 
    p = (int*)&i; 
    *p = 10;   // Causes runtime error 
} 

但在Windows系統中,一切都從RAM本身運行。

當我打印const變量和正常變量的地址時,我可以看到它們處於不同的偏移量。

系統如何知道指針訪問的地址是const

+5

鏈接器已將全局變量'i'放置在可執行映像的RO部分中。 –

+1

* p = 10個未定義的行爲。 – 2016-08-24 06:01:29

回答

5

嚴格來說,根據C語言標準,您的代碼會產生未定義的行爲。

實際上,鏈接器可能已將變量i放置在可執行映像的RO部分中。

因此寫操作*p = 10導致內存訪問衝突(又名分段錯誤)。

+0

RO =只讀... –

+0

RO部分是否駐留在RAM本身中? –

+0

@AllEldhose:我在這裏的評論的其餘部分不是由C語言標準決定的,但基本上取決於底層平臺(操作系統,虛擬內存,編譯器,鏈接器等)。通常,整個可執行映像被加載到RAM中。有時它的一部分可能會被「換出」到硬盤中,以便爲其他應用程序「騰出空間」。但基本上,當它運行時 - 它是從RAM運行的(再次,取決於你的平臺 - 例如,有硬件架構可以運行所有的Flash)。 –

4

系統如何知道....

理想情況下,系統不需要知道。對於具有const限定類型的對象,分配(一般情況下)將處於只讀部分,因此任何嘗試修改(寫入)都將導致訪問衝突。這是應該知道的程序員。

當我印刷const變量和正常變量的地址,我可以看到,他們在不同的偏移。

是的,這是有可能的,因爲正常變量駐留在讀寫內存,而const變量將駐留在只讀存儲器中。

請注意,有沒有語法(或編譯)錯誤爲您的代碼段。只有代碼(運行時)的行爲未定義。

僅供參考,引用C11,章§6.7.3/ P6

如果試圖通過與非常量限定左值的使用 修改與常量限定類型定義的對象類型,行爲是未定義的。 [...]

相關問題