【问题标题】:Actual C++ program memory layout on Windows (VS2010)Windows 上的实际 C++ 程序内存布局(VS2010)
【发布时间】:2014-02-10 21:26:41
【问题描述】:

最近我一直在阅读一些关于 C++ 内存布局和简化的文章,我知道有 3 个主要块:

  • 固定内存:代码、全局和静态变量
  • 堆栈内存:局部值和函数值
  • 堆内存:用户管理的内存(malloc/free new/delete)

根据我阅读的帖子,我假设在上述部分分配和拆分了一大块内存。

为了检查这一点,我创建了一个简单的程序:

#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;
}

然而,即使内存地址在上述内存块之间是一致的。 这些主要块的顺序从一个执行变为另一个执行。

                 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

这正常吗?这些块的位置取决于:操作系统,编译器?每个操作系统都会发生这种情况吗?谁能向我解释一下这个机制?

谢谢!

【问题讨论】:

    标签: c++ visual-studio-2010 memory layout


    【解决方案1】:

    操作系统主宰一切。

    首先,现代代码是可重定位的。几乎一个操作系统,尤其是 Windows,会在加载程序时动态地确定程序运行的位置。这对于使 DLL 一起运行非常重要,但它随时可能发生。

    看看这个:http://en.wikipedia.org/wiki/Portable_Executable

    此外,您的程序可以使用的堆栈数量可能会发生变化。

    【讨论】:

      【解决方案2】:

      您可以通过转到您的项目设置并转到:

      至少为基地址禁用此功能
      Project|Properties|Linker|Advanced|Randomize Base Address
      

      将此条目设置为“否 (/DYNAMICBASE:NO)”

      您也可以使用固定基址 (/FIXED /BASE)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-11
        • 1970-01-01
        • 1970-01-01
        • 2013-05-24
        • 2013-07-12
        • 1970-01-01
        相关资源
        最近更新 更多