C 找出指针是指向堆栈、堆还是程序文本?
是否有办法确定指针是否指向以下位置:C 找出指针是指向堆栈、堆还是程序文本?,c,pointers,C,Pointers,是否有办法确定指针是否指向以下位置: 堆栈 堆 或者该程序(如果是,请选择哪一部分,例如elf.text) 此外,这是否可以通过可移植的方式(Linux 64/32位、OSX和Windows 7+)实现 跟进: 我不是想知道是否有什么东西被破坏了 我想有效地区分程序中函数的void*指针和堆栈或堆中数据的void*指针 这适用于用C编写的语言运行时,而不是“普通”C程序 到目前为止,这个答案是最有用的:您不能以可移植的方式做您想做的事情,因为C语言标准没有将堆栈、程序区域和堆指定为不同的区域
- 堆栈
- 堆
- 或者该程序(如果是,请选择哪一部分,例如elf.text)
到目前为止,这个答案是最有用的:您不能以可移植的方式做您想做的事情,因为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;
}
根据上面的内容,您可以确定(可能)堆是从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:
program: 0x8048524
heap: 0x804b030
heap2: 0x804b040
stack: 0xbfbffb3c
stack2: 0xbfbffb1c
program: 0x400770
heap: 0x801006058
heap2: 0x801006060
stack: 0x7fffffffdaec
stack2: 0x7fffffffdabc
英特尔64位FreeBSD下的gcc:
program: 0x8048524
heap: 0x804b030
heap2: 0x804b040
stack: 0xbfbffb3c
stack2: 0xbfbffb1c
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
program: 0x842c
heap: 0xb63008
heap2: 0xb63018
stack: 0xbe83eac4
stack2: 0xbe83eaac
StrongARM运行NetBSD:
program: 0x1c5c
heap: 0x5030
heap2: 0x5040
stack: 0xefbfdcd0
stack2: 0xefbfdcb4
以及运行Linux的ARMv6:
program: 0x10000514
heap: 0x100c6008
heap2: 0x100c6018
stack: 0xbff45db0
stack2: 0xbff45d88
program: 0x842c
heap: 0xb63008
heap2: 0xb63018
stack: 0xbe83eac4
stack2: 0xbe83eaac
正如您所看到的,可能性是无穷的。一般来说,您可以确定堆栈和堆的位置,尽管它的大小将是另一回事
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;
}
有点粗鲁,除非您处理的是指定的平台,否则您无法绝对确定这两个平台的扩展方向或大小。请参阅的答案。在Windows上,您可以使用WinDbg的
!地址
为您确定此地址的扩展名。我不知道基于*nix的操作系统。在Linux下,/proc/self/maps为我提供了我需要的所有信息。您是否忘记了创建heap2
的代码行?