探讨和内存有关的问题:Windows平台下,如果使用C++输出指针的值(即地址),输出的是虚拟地址吗?

C++语言 码拜 10年前 (2015-05-11) 1180次浏览 0个评论
 

研究这个问题,因为是我在看内存管理的时候,在百度文档看到了这个: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;
}

以下是四次运行的不同结果
探讨和内存有关的问题:Windows平台下,如果使用C++输出指针的值(即地址),输出的是虚拟地址吗?

要深入一点探讨这样的问题,可能不是靠几下打印测试就会有结论的吧.
不妨学习PE规范,Windows技术内幕,这样或许才能获得比较深刻的理解.

至于c++对象模型,有些这方面的书籍可以参考.如<<深度探索c++对象模型>>.

个人意见,仅供参考.

20分
挺奇怪,按我的认知,应该每次运行结果都一样才对。因为:
1、指针输出的是虚拟地址。
2、可执行程序来说,栈上地址应该是编译时确定的。
我刚才专门试了一下GCC和VC2010,多次运行的输出都是一样的。
所以,你这是什么情况……
引用 1 楼 JiMoKuangXiangQu 的回复:

要深入一点探讨这样的问题,可能不是靠几下打印测试就会有结论的吧.
不妨学习PE规范,Windows技术内幕,这样或许才能获得比较深刻的理解.

至于c++对象模型,有些这方面的书籍可以参考.如<<深度探索c++对象模型>>.

个人意见,仅供参考.

这个扯远了点,看完这几本书,楼主也不会来问这个问题了,哈哈。

引用 2 楼 nossiac 的回复:

挺奇怪,按我的认知,应该每次运行结果都一样才对。因为:
1、指针输出的是虚拟地址。
2、可执行程序来说,栈上地址应该是编译时确定的。
我刚才专门试了一下GCC和VC2010,多次运行的输出都是一样的。
所以,你这是什么情况……

我换了G++试了一下,结果地址不变……

lz,《深入理解计算机体系结构》里面有lz想要的答案
引用 1 楼 JiMoKuangXiangQu 的回复:

要深入一点探讨这样的问题,可能不是靠几下打印测试就会有结论的吧.
不妨学习PE规范,Windows技术内幕,这样或许才能获得比较深刻的理解.

至于c++对象模型,有些这方面的书籍可以参考.如<<深度探索c++对象模型>>.

个人意见,仅供参考.

引用 5 楼 houzhenghui123 的回复:

lz,《深入理解计算机体系结构》里面有lz想要的答案

其实我问这个问题其实就是为了搞清楚,编译器在编译一条“输出一个指针值”的语句的时候,是怎么编译的,是不是把段寄存器里面的地址也加上去而已。所以为了搞清楚这个问题我还是去看看汇编代码更好……

20分
引用 6 楼 Geterns 的回复:

其实我问这个问题其实就是为了搞清楚,编译器在编译一条“输出一个指针值”的语句的时候,是怎么编译的,是不是把段寄存器里面的地址也加上去而已。所以为了搞清楚这个问题我还是去看看汇编代码更好…… 

编译器不用计算到段地址吧……
编译器只需要算出虚拟地址就行了,后面寻址的是执行时loader和CPU的事了。

楼主,这个问题解决了吗?我今天看到windows中虚拟地址的相关问题,授到了你们的讨论。我在vs2010中得到的结果也是输出变化的地址(一次编译)。这是为什么呢?

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明探讨和内存有关的问题:Windows平台下,如果使用C++输出指针的值(即地址),输出的是虚拟地址吗?
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!