内存应用程序布局

时间:2010-09-09 12:26:01

标签: c++ c memory memory-management

以下问题对我来说是一个令人头疼的问题。假设我有两个平台 具有相同的硬件,相同的操作系统和相同的编译器。如果我完全编译 相同的应用程序,我可以确定两台机器上的内存布局完全相同吗?换句话说,两个应用程序都具有相同的虚拟地址空间 很有可能事实并非如此。

感谢您对此的看法!

5 个答案:

答案 0 :(得分:7)

你不能指望它。作为一种安全功能,某些操作系统(包括Windows)会在一定程度上随机化内存布局。

(这是支持链接:http://blogs.msdn.com/b/winsdk/archive/2009/11/30/how-to-disable-address-space-layout-randomization-aslr.aspx

答案 1 :(得分:1)

极不可能应用程序将在同一平台上的相同地址空间中执行,但仍然在另一台计算机上执行。其他应用程序可能正在运行,这将影响操作系统加载应用程序的位置

需要考虑的另一点是,某些应用程序会根据需要加载运行时库(例如,DLL和共享库)。当您的应用程序运行时,应用程序可能会加载一些DLL。

在非嵌入式平台中,大多数应用程序并不关心确切的物理内存位置,也不关心每次都将它们加载到同一位置。大多数嵌入式平台每次都将应用程序加载到同一个地方,因为它们没有足够的内存来移动它们。

由于这些情况以及其他人提到的情况,请勿将常规内存位置原则编入您的程序。会发生非常糟糕的事情,特别是难以跟踪和调试。

答案 2 :(得分:0)

除了Steven指出的堆栈地址等动态问题外,还有编译时和静态布局等方面。

我已经认为两台机器完全相互克隆是一个非常特殊的情况,因为你可能在CPU版本,库等方面存在细微的差别。然后一些编译器(可能依赖于某些选项)也将编译时间和可执行文件中的日期。例如,如果您的两个主机名具有不同的长度或者使用长度不同的日期格式,则不仅这些字符串会有所不同,而且所有其他静态变量可能会在地址空间中稍微移位。

我记得gcc在自动构建的某些体系结构上遇到了困难,因为第2阶段生成的编译器由于这些愚蠢的原因而与第3阶段的编译不同。

答案 3 :(得分:0)

__TIME__宏扩展到(编译时)的开头。此外,它已确定 独立于您编译的每个.cpp文件,链接器可以消除重复的字符串。

因此,根据编译速度,您的可执行文件最终可能不只是使用不同的__TIME__字符串,而是使用不同数量的__TIME__字符串。

如果你工作到很晚,你可以看到与__DATE__字符串相同的内容;)

答案 4 :(得分:0)

可能是否具有相同的内存布局?是的,这是一种可能性。是可能?不是真的。

正如其他人所指出的那样,地址空间随机化和__TIME__宏之类的东西可能导致地址空间不同(无论是在编译时还是在运行时进行了更改)。根据我的经验,当使用完全相同的输入在同一台机器上运行两次时,许多编译器不会产生相同的相同输出(函数在内存中以不同的顺序排列等)。

这是一个修辞/智力问题,还是这会导致你在编写某个程序时遇到某种问题?