为什么每次运行时函数的地址都会改变?

Bor*_*rph 3 c++ function-pointers

我正在努力将地址映射到它们的符号以进行调试(获取callstack).该MS dbghelp.dll可以从地址(见告诉符号SymFromAddr,MSDN).但是,它不起作用,我想知道这是如何工作的,因为地址似乎随着程序的每次运行而改变:

#include <iostream>
void Foo() {}

int _tmain(int argc, _TCHAR* argv[])
{
    const long unsigned int addr = reinterpret_cast<long unsigned int>(&Foo);
    std::cout << "Address: " << std::hex << addr << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

D:\dev\Sandbox\Debug>Sandbox.exe
Address: 901320
D:\dev\Sandbox\Debug>Sandbox.exe
Address: ce1320
D:\dev\Sandbox\Debug>Sandbox.exe
Address: 3a1320
D:\dev\Sandbox\Debug>Sandbox.exe
Address: 3f1320
Run Code Online (Sandbox Code Playgroud)

一个不同的程序如何从堆栈跟踪中读取地址并将其映射到函数?这对我来说听起来很神奇.我没有在链接文档中找到任何说明我必须从地址或其他内容中减去一些内容的内容.

根据我的理解,因为我们克服了实模式,所以每个进程都有一个虚拟内存空间,所以不需要再为掷骰子加载地址了.我会理解DLL的绝对地址的不确定性,但不是主要的可执行文件.

用VS2008试用Win7.