研究这个问题,因为是我在看内存管理的时候,在百度文档看到了这个:http://wenku.baidu.com/view/d1f07821bcd126fff7050b87.html 这个文档说,同一份程序代码,多次运行,重新编译之后运行,输出地地址都应该是相同的?我自己用VS2010编译运行了一下,怎么结果是不同的? 深究这个问题,让我们先从Windows内存管理开始。 Windows内存模式的特点之一是“段”(即使是使用平坦内存模式,也可以把它看做是一种特殊的段模式),使用段模式可以表达一个逻辑地址segment:offset 以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; } 以下是四次运行的不同结果 |
|
要深入一点探讨这样的问题,可能不是靠几下打印测试就会有结论的吧.
不妨学习PE规范,Windows技术内幕,这样或许才能获得比较深刻的理解. 至于c++对象模型,有些这方面的书籍可以参考.如<<深度探索c++对象模型>>. 个人意见,仅供参考. |
|
20分 |
挺奇怪,按我的认知,应该每次运行结果都一样才对。因为:
1、指针输出的是虚拟地址。 2、可执行程序来说,栈上地址应该是编译时确定的。 我刚才专门试了一下GCC和VC2010,多次运行的输出都是一样的。 所以,你这是什么情况…… |
这个扯远了点,看完这几本书,楼主也不会来问这个问题了,哈哈。 |
|
我换了G++试了一下,结果地址不变…… |
|
lz,《深入理解计算机体系结构》里面有lz想要的答案
|
|
其实我问这个问题其实就是为了搞清楚,编译器在编译一条“输出一个指针值”的语句的时候,是怎么编译的,是不是把段寄存器里面的地址也加上去而已。所以为了搞清楚这个问题我还是去看看汇编代码更好…… |
|
20分 |
编译器不用计算到段地址吧…… |
楼主,这个问题解决了吗?我今天看到windows中虚拟地址的相关问题,授到了你们的讨论。我在vs2010中得到的结果也是输出变化的地址(一次编译)。这是为什么呢?
|