2012-08-06 35 views
6

我有一个指针可用于我的C/C++变量。是否有可能准确地确定这个变量属于哪一段内存?如果是,如何?确定一个地址是否属于堆或堆栈或寄存器

注:我只是有这个变量的地址,如果变量没有进一步的信息是局部/全局等

+8

不可能的,至少不是在一个可移植的方式。 – juanchopanza 2012-08-06 11:52:02

+3

你想解决什么问题?你需要一个运行时还是编译时解决方案?寄存器没有地址。 – 2012-08-06 11:52:59

+0

我们只是有一个参数,不管全局变量是属于堆栈还是堆,都想确认自己:P – 2012-08-06 11:58:23

回答

2

了解你的架构是否有指向你的堆或叠区域。通常有一些stackpointers或framepointers ..

然后比较你的实际地址,这些地址,并决定他们属于哪里。

+0

呵呵,是的,你是对的;)但是如果你谈论异国情调的架构,也可以把全局变量放入堆栈或堆中。这也取决于架构。 – duedl0r 2012-08-06 12:11:30

+0

我有没有提到Univac硬件没有堆栈? .-) – 2012-08-06 12:14:54

+0

我只相信1981年以后发明的东西hehehe:D – duedl0r 2012-08-06 12:17:39

1

您可以首先确定可执行文件中不同部分的开始和结尾是什么。对于这一点,你需要最终在连接器脚本中添加一些变量围绕每一个部分是这样的:

SECTIONS { 
    [...] 
    .data : { 
     data_start = .; 
     *(.data) 
     data_end = .; 
    } 
    [...] 
} 

然后你可以在你的C/C++代码声明这些变量作为外部和直接使用它们来比较你的地址想识别。

调整链接器脚本可能并不容易。使用gcc,您可以将其转储为:

gcc -Wl,-verbose whatever.c 

然后尝试查找已在(messy)输出中定义的变量。

为了得到堆栈的边界,你可以在main()函数的开头实例化一个虚拟变量,并将其地址保存为栈顶,然后在当前位置实例化另一个,给你的底部。但是请注意,编译器的行为可能与此不完全相同(C中变量的堆栈顺序不能保证,甚至不能使用堆栈),所以这应该可行,但不能移植。

最后,对于堆,我没有任何把戏。我只是推断一个不在data/bss /派生的变量,而不是堆栈中的变量将在堆中(不包括寄存器),但是如果你能得到地址,我敢打赌编译器永远不会使用寄存器存储)。

2

如果您使用的是Linux(不知道其他Unix系统),你也许可以找到该文件中的信息/proc/<pid>/maps

0

我完全不知道这是否符合你的情况,但你可以尝试objdump -t查看elf文件的符号表。所有你需要的是你的变量的地址。在那里你可以找到显示每个变量部分的标志。有关更多详细信息,请参阅objdump手册页。

输出示例:

0804a020 g  O .bss 00000004    var 

它说varg叶形O bject在地址0804a020,部分.bss