簡體   English   中英

為什么指針/變量內存地址不會改變?

[英]Why do pointer / variable memory addresses not change?

#include <iostream>
using namespace std;

int main(void)
{
    int *ptr = new int;
    cout << "Memory address of ptr:" << ptr << endl;
    cin.get();
    delete ptr;

    return 0;
}

每次運行這個程序時,我都會獲得ptr的相同內存地址。 為什么?

[注意:我的回答是假設你正在使用一個使用虛擬內存系統的現代操作系統。

由於虛擬內存,每個進程都在其自己唯一的地址空間中運行,該地址空間獨立於任何其他進程並且不受任何其他進程的影響。 您從new獲得的地址是一個虛擬地址 ,由您的編譯器執行的new選擇生成。 *沒有理由這不是確定性的。

另一方面,與虛擬內存地址關聯的物理地址每次都很可能會有所不同,並會受到各種因素的影響。 該映射由OS控制。


* new可能是以malloc

我會說這主要是巧合。 因為內存分配器/操作系統可以為您提供它想要的任何地址。

您獲得的地址顯然不是均勻隨機的(並且高度依賴於其他OS因素),因此通常在行中多次獲得相同(虛擬)地址。

例如,在我的機器上:使用VS2010編譯的Window 7,我得到不同運行的不同地址:

00134C40
00124C40
00214C40
00034C40
00144C40
001B4C40

這是您的環境的工件。 cin.get()向我建議你在Visual Studio中編譯和執行,它提供了一個異常可預測的運行時環境。 當我在我的linux上編譯並運行該代碼時,兩次執行給出了兩個不同的地址。

ETA:
在評論中,您表示期望不同的進程可以獲得相同的內存地址,並且該地址將無法訪問您的程序。 在任何現代操作系統中都不是這種情況,因為操作系統為每個進程提供虛擬內存地址空間。

只有操作系統才能看到真正的硬件地址,並維護每個程序的虛擬內存映射,將虛擬地址重定向到物理地址。 因此,任意數量的不同進程可以將數據保存在同一虛擬地址中,而操作系統將該地址映射到每個進程的單獨物理地址。

這保證了進程A不能讀取或寫入進程B正在使用的存儲器而沒有啟用這種訪問的特殊規定(例如通過指示OS將某些進程中的某些虛擬存儲器映射到同一物理存儲器)。 它允許操作系統使不同類型的內存硬件對程序透明。

它還允許操作系統將程序的數據移到其后面,以優化系統性能。 經典示例:將一段時間未使用的數據移動到硬盤上的特殊文件中。 這有時稱為頁面文件

內存映射通常分為多個頁面 :一定大小的連續內存塊( 頁面大小 )。 虛擬地址空間頁面中保存的數據通常在物理內存中也是連續的,但如果數據在頁面邊界上運行,則在虛擬內存中看起來連續的信息可以很容易地分開。 如果C / C ++程序進入未定義的行為,它可能會嘗試訪問操作系統尚未映射到物理內存的頁面中的內存。 這將導致操作系統生成錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM