2014-02-10 35 views
0

最近我一直在閱讀一些文章關於C++的內存佈局,並且便於我知道有3個主要模塊:實際C++在Windows(VS2010)程序內存佈局

  • 固定的內存:代碼,全局和靜態變量
  • 棧存儲器:局部值和函數值
  • 堆內存:存儲器由用戶(的malloc /免費新/刪除)
  • 管理

根據我閱讀的文章,我假設在上述部分分配和分割大塊內存。

要檢查這個我已經創建了一個簡單的程序:

#include <stdio.h> 

int g_loopCount; 
static int gs_one = 1; 

int getLifeResult(int a) 
{ 
    printf("&a  %d\t\t%p\n", g_loopCount, &a); 
    if(++g_loopCount < 4) 
    { 
     getLifeResult(a); 
    } 
    else 
    { 
     return g_loopCount * 10 + a; 
    } 
} 

int main() 
{ 
    //fixed 
    printf("-fixed-\n"); 
    printf("&gs_one\t\t\t%p\n", &gs_one); 
    g_loopCount = 0; 
    printf("&g_loopCount\t\t%p\n\n", &g_loopCount); 

    int* lifeResult = new int(0); 
    int* lifeResultCopy = new int(0); 

    //stack 
    printf("-stack-\n"); 
    printf("&lifeResult\t\t%p\n", &lifeResult); 
    printf("&lifeResultC\t\t%p\n", &lifeResultCopy); 
    *lifeResult = getLifeResult(2); 
    *lifeResultCopy = *lifeResult; 
    printf("\n"); 

    //heap 
    printf("-heap-\n"); 
    printf("lifeResult\t\t%p\n", lifeResult); 
    printf("lifeResultC\t\t%p\n\n", lifeResultCopy); 

    return *lifeResult; 
} 

然而即使存儲ADRESS都在提到內存塊之間是一致的。 這些主塊的順序從一個執行變爲另一個執行。

    run 0  run 1   run 2 
-fixed- 
&gs_one   00E37000 00A37000 00047000 
&g_loopCount  00E37140 00A37140 00047140 

-stack- 
&lifeResult  0037FD6C 0030FD44 003EF784 
&lifeResultC  0037FD60 0030FD38 003EF778 
&a  0   0037FC70 0030FC48 003EF688 
&a  1   0037FB98 0030FB70 003EF5B0 
&a  2   0037FAC0 0030FA98 003EF4D8 
&a  3   0037F9E8 0030F9C0 003EF400 

-heap- 
lifeResult  00684670 00184670 00724670 
lifeResultC  006846B0 001846B0 007246B0 

這是正常的嗎?這些塊的位置取決於:操作系統,編譯器?它發生在每個操作系統上嗎?任何人都可以更詳細地解釋一下這個機制嗎?

謝謝!

回答

2

操作系統統治着一切。

首先,現代代碼是可重新定位的。非常多的操作系統,尤其是Windows,會在加載時動態地運行程序。這對於讓DLL一起玩是非常重要的,但它可以在任何時候發生。

檢查了這一點:http://en.wikipedia.org/wiki/Portable_Executable

此外,棧程序可以消耗的量可以改變。

1

你至少可以爲基地址禁用此功能,通過將您的項目設置,並轉到:

Project|Properties|Linker|Advanced|Randomize Base Address 

將該項設置爲「否(/ DYNAMICBASE:否)」

你也可以使用固定的基地址(/ FIXED/BASE)