2014-04-28 71 views
3

我在Matlab中編程了相當多的研究生水平數值分析課程和統計模擬,但我現在試圖學習更通用的語言。我自學C++,使用Lippman的「C++ Primer」。在完成關於指針的部分的同時,我遇到了讓我困惑的事情。我編譯和運行下面的代碼:如何分配內存寄存器的名稱?

#include <iostream> 

int main() { 
    int ival = 42; 
    int *p = &ival; 

    std::cout << p << std::endl; 
} 

我打算給這個給我的內存地址ival舉行,它似乎工作。這是輸出:

$ g++ pointer.cpp -o pointer 
$ ./pointer 
0x7fff5fbffa7c 

這使我困惑了幾個原因。

1)這是一個12位十六進制數字。這似乎意味着至少有16^12(= 2^48)位(或字節)的可用存儲空間。但是,我安裝了4 GB的DDR3 RAM,所以我應該只有4 * 2^30字節= 32 * 2^30位= 2^35位的可用存儲空間。所以,我的問題是:這個地址是在RAM中,還是在處理器的緩存中?如果它在RAM中,RAM中的內存寄存器如何標記?或者,我完全脫離了商標?在我的RAM中看起來似乎不可能存在與每12位十六進制數相對應的存儲器寄存器(甚至是11位數字,如果最左邊的數字保持不變)。

2)每次運行程序時,ival都存儲在完全相同的地方。如果我重命名變量並改變它的值,這仍然是正確的。如果創建第二個變量,KVAL,它的位置是在:

0x7fff5fbffa78 

4個字節IVAL的位置了。 (我現在假設地址以字節爲單位進行標記,因爲int使用4個字節。)C++編譯器在構建程序時是否總是以相同的內存地址開始?

我正在使用4GB DDR3 RAM和6 MB二級高速緩存(我知道這是一臺5年前的機器)的MacBook Pro,並且正在使用g ++編譯器。我希望最終能夠學會大會,真正理解這些事情是如何工作的,這就是爲什麼我要深入瞭解這一點。

我試圖在谷歌和Stack Overflow上找到這些信息,但一直沒有任何運氣。另外,據我所知,這在我正在處理的C++書中沒有得到解決。

預先感謝您的時間,請讓我知道是否有任何其他信息會有所幫助。

回答

2

兩個字 - 虛擬內存。您在代碼中看到的內存地址不是物理內存地址,它們是操作系統在後臺映射到物理內存地址的虛擬內存地址。這讓操作系統允許不同的進程在內部使用相同的內存地址,但保持它們在物理上相互隔離,將每個進程的虛擬內存池映射到物理內存的不同區域,或者在可用內存耗盡時甚至映射到硬盤空間。

輸出包含超過8個十六進制數字的事實意味着您可能正在編譯一個64位程序(使用最多16個十六進制數字的地址)。如果你重新編譯了32bit的程序,你會看到不同的輸出。

+0

謝謝你的回覆。這正是我正在尋找的。我覺得還有一些我不瞭解的東西。我感謝幫助! –

2
  1. 你的操作系統實現virtual memory。內存不是連續分配的,所以你的指針確實指向有效的內存(從你的進程的角度來看)。

  2. C++編譯器可能會將類似程序中的變量放在類似的位置。但是,它不僅取決於編譯器,操作系統也可能會影響到這一點(例如,使用ASLR)。

+0

謝謝你的回覆。我不知道額外的虛擬內存層。我會加快你的回答,但由於我是新人,我還沒有足夠高的聲望。再次感謝! –

2
  1. 地址是指針「p」在進程「虛擬」內存中的位置。閱讀「虛擬內存管理」瞭解操作系統如何管理內存。維基百科有一篇很好的文章:Virtual Memory

  2. 本地變量的地址取決於兩件事情:1.編譯器和2.操作系統加載進程的文本段。大多數編譯器會執行一些可能導致變量被移動的優化技術。如果操作系統實現完整的ASLR,則絕對位置也會改變。

+0

謝謝你的回覆。我不知道額外的虛擬內存層。我會加快你的回答,但由於我是新人,我還沒有足夠高的聲望。再次感謝! –