内存应用程序布局

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

谢谢你对此的看法!

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

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

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

另一个需要考虑的问题是,某些应用程序会根据需要加载运行时库(即DLL和共享库)。 应用程序运行时,应用程序可能会加载或不加载一些DLL。

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

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

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

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

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

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

因此,根据编译速度,您的可执行文件可能不仅会使用不同的__TIME__字符串,而且甚至会有不同数量的__TIME__字符串。

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

他们有可能拥有相同的内存布局吗? 是的,这是一种可能性。 可能吗? 并不是的。

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

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