以下问题对我来说是一个令人头疼的问题。假设我有两个平台 具有相同的硬件,相同的操作系统和相同的编译器。如果我完全编译 相同的应用程序,我可以确定两台机器上的内存布局完全相同吗?换句话说,两个应用程序都具有相同的虚拟地址空间 很有可能事实并非如此。
感谢您对此的看法!
答案 0 :(得分:7)
你不能指望它。作为一种安全功能,某些操作系统(包括Windows)会在一定程度上随机化内存布局。
答案 1 :(得分:1)
极不可能应用程序将在同一平台上的相同地址空间中执行,但仍然在另一台计算机上执行。其他应用程序可能正在运行,这将影响操作系统加载应用程序的位置
需要考虑的另一点是,某些应用程序会根据需要加载运行时库(例如,DLL和共享库)。当您的应用程序运行时,应用程序可能会加载一些DLL。
在非嵌入式平台中,大多数应用程序并不关心确切的物理内存位置,也不关心每次都将它们加载到同一位置。大多数嵌入式平台每次都将应用程序加载到同一个地方,因为它们没有足够的内存来移动它们。
由于这些情况以及其他人提到的情况,请勿将常规内存位置原则编入您的程序。会发生非常糟糕的事情,特别是难以跟踪和调试。
答案 2 :(得分:0)
除了Steven指出的堆栈地址等动态问题外,还有编译时和静态布局等方面。
我已经认为两台机器完全相互克隆是一个非常特殊的情况,因为你可能在CPU版本,库等方面存在细微的差别。然后一些编译器(可能依赖于某些选项)也将编译时间和可执行文件中的日期。例如,如果您的两个主机名具有不同的长度或者使用长度不同的日期格式,则不仅这些字符串会有所不同,而且所有其他静态变量可能会在地址空间中稍微移位。
我记得gcc
在自动构建的某些体系结构上遇到了困难,因为第2阶段生成的编译器由于这些愚蠢的原因而与第3阶段的编译不同。
答案 3 :(得分:0)
__TIME__
宏扩展到(编译时)的开头。此外,它已确定
独立于您编译的每个.cpp文件,链接器可以消除重复的字符串。
因此,根据编译速度,您的可执行文件最终可能不只是使用不同的__TIME__
字符串,而是使用不同数量的__TIME__
字符串。
如果你工作到很晚,你可以看到与__DATE__
字符串相同的内容;)
答案 4 :(得分:0)
可能是否具有相同的内存布局?是的,这是一种可能性。是可能?不是真的。
正如其他人所指出的那样,地址空间随机化和__TIME__
宏之类的东西可能导致地址空间不同(无论是在编译时还是在运行时进行了更改)。根据我的经验,当使用完全相同的输入在同一台机器上运行两次时,许多编译器不会产生相同的相同输出(函数在内存中以不同的顺序排列等)。
这是一个修辞/智力问题,还是这会导致你在编写某个程序时遇到某种问题?