它的全局变量的地址对于程序的不同运行是相同的
Is address of global variables the same for different runs of the program?
考虑以下代码片段
int i=10;
int main()
{
cout<<&i;
}
一旦为程序生成了exe,对于程序的不同运行,输出是否相同?假设操作系统支持虚拟内存
编辑:这个问题是特定于全局变量存储在数据段。因为这是第一个全局变量,地址应该是相同的还是不同的?
如果ASLR被禁用,您总是得到相同的地址。如果启用ASLR,您将获得不可预测的地址。
虚拟地址将由链接器决定。物理地址将随每次加载而变化。
简单回答:看情况:-)
如果你的操作系统总是在相同的环境下启动一个程序,并且虚拟内存范围看起来总是相同的,那么输出应该总是相同的。
但是如果你在不同的硬件上运行相同的操作系统(可能有不同数量的可用内存),它可能会导致不同的地址,但通常地址也是相同的,独立于硬件。
但是你不应该期望结果是相同的!简而言之:不要考虑程序中数据的虚拟地址或真实地址。这是由编译器、操作系统和一些库控制的。所以忽略它吧!
简短的回答:在x86-64机器上运行的用户模式程序:不,您不应该假设无论出于何种原因。
长话短说:地址可能是相同的,但这绝对不能保证(至少在x86_64操作系统和机器上运行的程序上)。
我读到一些关于虚拟/物理内存的混淆,以及为什么地址是"随机",所以让我从高层次的角度解释一些事情:
针对x86_64架构和操作系统(让我们说Windows),你甚至不能假设操作系统本身会将其所有组件加载到相同物理位置的内存中(一些例外的旧引导加载程序约定在000:7 c00h,我不知道这在UEFI环境中是如何工作的)。
在段(是否使用取决于操作系统,通常Windows只是为用户模式和内核模式设置了一些普通段)被放置之后,一旦你切换到保护模式(或长),你就无法控制操作系统如何管理虚拟内存机制,它隐藏了复杂的层和mmu相关的操作,给你的进程一个自己的地址空间。
另外还有安全措施:链接器可能决定你的可执行文件的基址,但在其他情况下,当ASLR被激活时,操作系统可以随意移动它的模块和你的可执行文件,因为它喜欢安全的目的。
结论:除非你在处理非常低级的东西(例如物理地址或直接写入外部设备的内存区域),否则你绝对不应该依赖变量的地址在不同的运行中是相同的。没有保证
- 如何通过cpp程序运行shell脚本
- 如何在GTK程序运行时禁用屏幕保护程序/电源管理/屏幕消隐
- 在程序运行时监视 VxWorks 中的任务 CPU 利用率
- 无法在 VS Code 上使用代码运行程序运行C++文件
- 程序运行,但文件无法打开.C++中的命令行
- 终端命令在程序运行后自动打开图形
- 程序运行,但并非所有内容都显示出来
- 为什么程序运行时我的第二个循环不执行?
- 如何在 c++ 程序运行时隐藏控制台?
- 通过C++应用程序运行 shell 脚本始于 JAVA
- C++字数统计程序使用C字符串错误在程序运行后
- 我的程序运行良好,可以复制对象,但是当我使用复制分配(=)时,它仍然可以正常运行.为什么不给错误
- 如何修复数据库连接的C 程序运行时间错误(0xc0000005)
- 如何通过C++程序运行Windows命令?
- 在程序运行时更改 DLL
- 程序运行时,未读取文件
- C 是否有办法使程序运行,只要引入了新值
- CreateProcess:某些应用程序运行其他应用程序
- 使用一个 C 程序运行 python 脚本(不同的 python 版本)
- 从 WebAPI 项目运行静态类时出现 StackOverflow 异常 - 从控制台应用程序运行时工作正常