c語言中的虛擬位址

2021-08-19 18:34:48 字數 1592 閱讀 2976

在c語言中,指標變數的值就是乙個記憶體位址,

&運算子的作用也是取變數的記憶體位址,請看下面的**:

#include #include int a = 1, b = 255;

int main()

程式執行結果為:

pa = 0x402000, &b = 0x402004

**中的 a、b 是全域性變數,它們的記憶體位址在鏈結時就已經決定了,以後再也不能改變,該程式無論在何時執行,結果都是一樣的。

那麼問題來了,如果物理記憶體中的這兩個位址被其他程式占用了怎麼辦,我們的程式豈不是無法執行了?

幸運的是,這些記憶體位址都是假的,不是真實的物理記憶體位址,而是虛擬位址。虛擬位址通過cpu的轉換才能對應到實體地址,而且每次程式執行時,作業系統都會重新安排虛擬位址和實體地址的對應關係,哪一段物理記憶體空閒就使用哪一段。如下圖所示:

虛擬位址的整個想法是這樣的:把程式給出的位址看做是一種

虛擬位址

(virtual address),然後通過某些對映的方法,將這個虛擬位址轉換成實際的實體地址。這樣,只要我們能夠妥善地控制這個虛擬位址到實體地址的對映過程,就可以保證程式每次執行時都可以使用相同的位址。

例如,上面**中變數 a 的位址是 0x402000,第一次執行時它對應的物理記憶體位址可能是 0x12ed90aa,第二次執行時可能又對應 0xed90,而我們的程式不需要關心這些,這些繁雜的記憶體管理工作交給作業系統處理即可。

讓我們回到程式的執行本質上來。使用者程式在執行時不希望介入到這些複雜的記憶體管理過程中,作為普通的程式,它需要的是乙個簡單的執行環境,有自己的記憶體,有自己的cpu,好像整個程式占有整個計算機而不用關心其他的程式。

除了在程式設計時可以使用固定的記憶體位址,給程式設計師帶來方便外,使用虛擬位址還能夠使不同程式的位址空間相互隔離,提高記憶體使用效率。

使不同程式的位址空間相互隔離

如果所有程式都直接使用物理記憶體,那麼程式所使用的位址空間不是相互隔離的。惡意程式可以很容易改寫其他程式的記憶體資料,以達到破壞的目的;有些非惡意、但是有 bug 的程式也可能會不小心修改其他程式的資料,導致其他程式崩潰。

這對於需要安全穩定的計算機環境的使用者來說是不能容忍的,使用者希望他在使用計算機的時候,其中乙個任務失敗了,至少不會影響其他任務。

使用了虛擬位址後,程式a和程式b雖然都可以訪問同乙個位址,但它們對應的實體地址是不同的,無論如何操作,都不會修改對方的記憶體。

提高記憶體使用效率

使用虛擬位址後,作業系統會更多地介入到記憶體管理工作中,這使得控制記憶體許可權成為可能。例如,我們希望儲存資料的記憶體沒有執行許可權,儲存**的記憶體沒有修改許可權,作業系統占用的記憶體普通程式沒有讀取許可權等。

另外,當物理記憶體不足時,作業系統能夠更加靈活地控制換入換出的粒度,磁碟 i/o 是非常耗時的工作,這能夠從很大程度上提高程式效能。

在計算機中,為了讓操作更加直觀、易於理解、增強使用者體驗,開發者經常會使用一件法寶——增加中間層,即使用一種間接的方式來遮蔽複雜的底層細節,只給使用者提供簡單的介面。虛擬位址是使用中間層的乙個典型例子。

實際上,計算機的整個發展過程就是不斷引入新的中間層:

C 虛擬位址空間

一 引言 在計算機中,每台裝置以及程序都被分配乙個位址空間。位址空間包括物理空間以及虛擬空間。如果將實體地址暴露給程序,使用者就很容易破壞作業系統,從而使系統停止 另外隨著程序數量和體積的增長,核心空間變得越來越不夠用,從而引入虛擬位址空間。實體地址 physical address 放在定址匯流排...

C記憶體3 虛擬位址

在c語言中有乙個指標這麼乙個煩人的東西,經常會涉及到記憶體位址等概念。int a 4 這段 儲存之後就存在硬碟上,之後對這個 操作要從硬碟上讀取到記憶體,最後cpu才計算,再將計算結果返回給記憶體。4既有乙個虛擬位址,還有乙個實體地址 這樣說對?還是4就對應乙個位址就是存在於實體地址中,之後a對應虛...

Tomcat虛擬位址

當不想把jsp程式 網頁等編寫的程式檔案部署在tomcat的根目錄下時,虛擬目錄是最好的選擇。虛擬目錄實際上是在伺服器上做乙個對映,把某個名稱命名的目錄指向另外乙個事實上存在的目錄,這樣可以增強安全性,訪問者並不清楚伺服器是否確實有無目錄,當伺服器某個盤中的空間不夠時,可以把程式部署到另乙個盤中做虛...