找出指针是指向堆栈,堆或程序文本吗?
是否有以找出是否一个指针在的位置处指向的方式:找出指针是指向堆栈,堆或程序文本吗?
- 堆栈
- 堆
- 或程序(并且如果是这样,这部分例如小精灵的.text) ?
此外,这可以做到可移植(Linux 64/32位,OSX和Windows 7 +)?
跟进:
我不会试图找出是否有什么东西被malloc分配。
我想有效地区分void *指针和程序中的函数void *指向堆栈或堆上的数据。
这是用C编写的语言运行库,而不是“普通的”C程序。
这个答案一直是最有用至今:Checking if something was malloced
你不能做你的便携式方式想要什么,因为C语言标准没有规定的堆栈,程序区和堆为不同的领域。它们的位置可以取决于处理器体系结构,操作系统,加载程序,链接程序和编译器。试图猜测指针指向的位置是否违反了C提供的抽象,所以你可能不应该这样做。
尽管如此,仍然有许多方法可以编写能够针对特定环境进行正确猜测的代码。您可以通过检查现有对象的地址并查找模式来做到这一点。考虑下面的程序。
#include <stdlib.h>
#include <stdio.h>
void
function()
{
int stack2;
printf("stack2: %15p\n", &stack2);
}
int
main(int argc, char *argv[])
{
int stack;
void *heap = malloc(1);
void *heap2 = malloc(1);
printf("program: %15p\n", main);
printf("heap: %15p\n", heap);
printf("heap2: %15p\n", heap2);
printf("stack: %15p\n", &stack);
function();
return 0;
}
通过检查其输出,您可以看到一个模式,例如x64 Linux上的以下模式。
program: 0x400504
heap: 0x1675010
heap2: 0x1675030
stack: 0x7fff282c783c
stack2: 0x7fff6ae37afc
从上面可以确定(可能)堆从0x1675010向上生长,它下面什么是程序代码(或静态数据,这些数据并没有提及),并且纸叠生长在一个不可预知的方式(可能是由于堆栈随机化)围绕一个非常大的地址,如0x7fff282c783c。
比较这与在32位Intel的Linux输出:
program: 0x804842f
heap: 0x804b008
heap2: 0x804b018
stack: 0xbf84ad38
stack2: 0xbf84ad14
Microsoft Windows和32位Microsoft C编译器:
program: 01271020
heap: 002E3B00
heap2: 002E3B10
stack: 0024F978
stack2: 0024F964
在Windows Cygwin的GCC:
program: 0040130B
heap: 00A41728
heap2: 00A417A8
stack: 0028FF44
stack2: 0028FF14
英特尔32位FreeBSD下的gcc:
0123在Intel 64位的FreeBSDprogram: 0x8048524
heap: 0x804b030
heap2: 0x804b040
stack: 0xbfbffb3c
stack2: 0xbfbffb1c
GCC:
program: 0x400770
heap: 0x801006058
heap2: 0x801006060
stack: 0x7fffffffdaec
stack2: 0x7fffffffdabc
GCC下SPARC-64的FreeBSD:
program: 0x100860
heap: 0x40c04098
heap2: 0x40c040a0
stack: 0x7fdffffe9ac
stack2: 0x7fdffffe8dc
的PowerPC运行的MacOS X:
program: 0x1ed4
heap: 0x100120
heap2: 0x100130
stack: 0xbffffba0
stack2: 0xbffffb38
的PowerPC运行Linux:
program: 0x10000514
heap: 0x100c6008
heap2: 0x100c6018
stack: 0xbff45db0
stack2: 0xbff45d88
的StrongARM运行的NetBSD:
program: 0x1c5c
heap: 0x5030
heap2: 0x5040
stack: 0xefbfdcd0
stack2: 0xefbfdcb4
和ARMv6的运行Linux:
program: 0x842c
heap: 0xb63008
heap2: 0xb63018
stack: 0xbe83eac4
stack2: 0xbe83eaac
正如你所看到的可能性是无穷无尽的。
+1。非常翔实的示范。 – 2013-05-03 14:43:29
在Linux下,/ proc/self/maps为我提供了所有我需要的信息。 – fadedbee 2013-05-07 07:32:58
你有没有忘记创建'heap2'的代码行? – 2015-01-19 19:54:56
可以大致判断栈和堆的来讲,虽然它是多么大的将是另一个故事的位置...
void *heap_locations;
void *stack_location;
void determine_locations (int any_int) {
free(heap_location = malloc(248));
stack_location = &any_int;
}
int main(int argc, char *argv[]) {
determine_locations(argc);
.
.
.
return 0;
}
有点粗鲁,你不会知道的扩张方向或大小要么绝对确定,除非你正在处理指定的平台。
请参阅[这个问题]的答案(http://*.com/questions/276612/checking-if-something-was-malloced)。 – 2013-05-03 14:02:49
在Windows上,您可以使用WinDbg的“!address”扩展名为您确定。我不知道基于nix的操作系统。 – user1354557 2013-05-03 14:24:24