探讨和内存有关的有关问题:Windows平台下,如果使用C++输出指针的值(即地址),输出的是虚拟地址吗
探讨和内存有关的问题:Windows平台下,如果使用C++输出指针的值(即地址),输出的是虚拟地址吗?
研究这个问题,因为是我在看内存管理的时候,在百度文档看到了这个:http://wenku.baidu.com/view/d1f07821bcd126fff7050b87.html
这个文档说,同一份程序代码,多次运行,重新编译之后运行,输出地地址都应该是相同的?我自己用VS2010编译运行了一下,怎么结果是不同的?
深究这个问题,让我们先从Windows内存管理开始。
Windows内存模式的特点之一是“段”(即使是使用平坦内存模式,也可以把它看做是一种特殊的段模式),使用段模式可以表达一个逻辑地址segment:offset
按照我的理解,一个程序的二进制代码中地址应该是offset,而启动这个程序时,操作系统会给它分配好一个segment
以32位的Windows为例,系统维护着4G的地址空间,我们把这个地址空间中的地址叫做虚拟地址,如果确定了逻辑地址,也就可以确定相应的虚拟地址。
那么,这个问题我的想法是这样的,如果说指针中的地址值是offset的值,那么的确,应该每一次运行offset值都是一样的;如果指针中的地址值是虚拟地址的值,那么应该会出现不同的情况。
不知道我的理解有没有错误的地方?难道我的实验结果说明指针输出的就是虚拟地址的值吗?
以下是四次运行的不同结果

------解决思路----------------------
挺奇怪,按我的认知,应该每次运行结果都一样才对。因为:
1、指针输出的是虚拟地址。
2、可执行程序来说,栈上地址应该是编译时确定的。
我刚才专门试了一下GCC和VC2010,多次运行的输出都是一样的。
所以,你这是什么情况……
------解决思路----------------------
编译器不用计算到段地址吧……
编译器只需要算出虚拟地址就行了,后面寻址的是执行时loader和CPU的事了。
研究这个问题,因为是我在看内存管理的时候,在百度文档看到了这个:http://wenku.baidu.com/view/d1f07821bcd126fff7050b87.html
这个文档说,同一份程序代码,多次运行,重新编译之后运行,输出地地址都应该是相同的?我自己用VS2010编译运行了一下,怎么结果是不同的?
深究这个问题,让我们先从Windows内存管理开始。
Windows内存模式的特点之一是“段”(即使是使用平坦内存模式,也可以把它看做是一种特殊的段模式),使用段模式可以表达一个逻辑地址segment:offset
按照我的理解,一个程序的二进制代码中地址应该是offset,而启动这个程序时,操作系统会给它分配好一个segment
以32位的Windows为例,系统维护着4G的地址空间,我们把这个地址空间中的地址叫做虚拟地址,如果确定了逻辑地址,也就可以确定相应的虚拟地址。
那么,这个问题我的想法是这样的,如果说指针中的地址值是offset的值,那么的确,应该每一次运行offset值都是一样的;如果指针中的地址值是虚拟地址的值,那么应该会出现不同的情况。
不知道我的理解有没有错误的地方?难道我的实验结果说明指针输出的就是虚拟地址的值吗?
#include <iostream>
using namespace std;
int main(){
int a, b, c;
cout << &a << endl << &b << endl << &c << endl;
return 0;
}
以下是四次运行的不同结果
------解决思路----------------------
挺奇怪,按我的认知,应该每次运行结果都一样才对。因为:
1、指针输出的是虚拟地址。
2、可执行程序来说,栈上地址应该是编译时确定的。
我刚才专门试了一下GCC和VC2010,多次运行的输出都是一样的。
所以,你这是什么情况……
------解决思路----------------------
编译器不用计算到段地址吧……
编译器只需要算出虚拟地址就行了,后面寻址的是执行时loader和CPU的事了。