找出指针是指向堆栈,堆或程序文本吗?

问题描述:

是否有以找出是否一个指针在的位置处指向的方式:找出指针是指向堆栈,堆或程序文本吗?

  • 堆栈
  • 或程序(并且如果是这样,这部分例如小精灵的.text) ?

此外,这可以做到可移植(Linux 64/32位,OSX和Windows 7 +)?

跟进:

我不会试图找出是否有什么东西被malloc分配。

我想有效地区分void *指针和程序中的函数void *指向堆栈或堆上的数据。

这是用C编写的语言运行库,而不是“普通的”C程序。

这个答案一直是最有用至今:Checking if something was malloced

+1

请参阅[这个问题]的答案(http://*.com/questions/276612/checking-if-something-was-malloced)。 – 2013-05-03 14:02:49

+0

在Windows上,您可以使用WinDbg的“!address”扩展名为您确定。我不知道基于nix的操作系统。 – user1354557 2013-05-03 14:24:24

你不能做你的便携式方式想要什么,因为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位的FreeBSD
program:  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 

正如你所看到的可能性是无穷无尽的。

+2

+1。非常翔实的示范。 – 2013-05-03 14:43:29

+0

在Linux下,/ proc/self/maps为我提供了所有我需要的信息。 – fadedbee 2013-05-07 07:32:58

+2

你有没有忘记创建'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; 
} 

有点粗鲁,你不会知道的扩张方向或大小要么绝对确定,除非你正在处理指定的平台。