c - 找出指针是否指向堆栈、堆或程序文本?

标签 c pointers

有没有办法找出指针是否指向以下位置:

  • 堆栈
  • 或程序(如果是,是哪个部分,例如 elf.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

Intel 32 位 FreeBSD 下的 gcc:

program:       0x8048524
heap:          0x804b030
heap2:         0x804b040
stack:        0xbfbffb3c
stack2:       0xbfbffb1c

Intel 64 位 FreeBSD 下的 gcc:

program:        0x400770
heap:        0x801006058
heap2:       0x801006060
stack:    0x7fffffffdaec
stack2:   0x7fffffffdabc

SPARC-64 FreeBSD 下的 gcc:

program:        0x100860
heap:         0x40c04098
heap2:        0x40c040a0
stack:     0x7fdffffe9ac
stack2:    0x7fdffffe8dc

运行 MacOS X 的 PowerPC:

program:          0x1ed4
heap:           0x100120
heap2:          0x100130
stack:        0xbffffba0
stack2:       0xbffffb38

运行 Linux 的 PowerPC:

program:      0x10000514
heap:         0x100c6008
heap2:        0x100c6018
stack:        0xbff45db0
stack2:       0xbff45d88

StrongARM 运行 NetBSD:

program:          0x1c5c
heap:             0x5030
heap2:            0x5040
stack:        0xefbfdcd0
stack2:       0xefbfdcb4

和运行 Linux 的 ARMv6:

program:          0x842c
heap:           0xb63008
heap2:          0xb63018
stack:        0xbe83eac4
stack2:       0xbe83eaac

如您所见,可能性是无限的。

关于c - 找出指针是否指向堆栈、堆或程序文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16360620/

相关文章:

c - 使用负数作为数组索引

c++ - 如何声明对标准算法的引用?

c++ - 当前实例成员函数的函数指针

c - 为什么 NSError 需要双重间接? (指向指针的指针)

C: 读地址错误

正确的格式说明符打印指针或地址?

c++ - 指针复制到范围外c++

c - 使用可用的 binaryrandom(返回 0 或 1)函数生成整数随机数

Android Studio - App + NDK 模块库

C 语言,段错误(已创建核心转储)