如何以编程方式获取Linux上堆的地址

我可以用sbrk(0)得到结束的地址,但有没有办法以编程方式获得堆的开始地址,而不是通过parsing/proc/self/maps

我认为解析/proc/self/maps是Linux上查找堆段的唯一可靠方法。 不要忘记,一些分配器(包括我的SLES中的一个)用于大块mmap()因此内存不再是堆的一部分,可以在任何随机位置。

否则,通常ld会添加一个符号来标记elf中所有段的结尾,并将该符号称为_end 。 例如:

 extern void *_end; printf( "%p\n", &_end ); 

它匹配.bss的结尾,传统上是精灵的最后一部分。 地址之后,有一些对齐,通常跟在堆上。 堆栈和mmap()(包括共享库)位于地址空间的较高地址处。

我不确定它的可移植性如何,但显然它在Solaris 10上的工作方式相同。在HP-UX 11上,映射看起来不同,堆似乎与数据段合并,但分配确实发生在_end 。 在AIX上, procmap根本不显示堆/数据段,但是分配也得到了超过_end符号的地址。 所以它现在似乎是非常便携的。

虽然,所有考虑,我不知道这是多么有用。

PS测试程序:

 #include <stdio.h> #include <stdlib.h> char *ppp1 = "hello world"; char ppp0[] = "hello world"; extern void *_end; /* any type would do, only its address is important */ int main() { void *p = calloc(10000,1); printf( "end:%p heap:%p rodata:%p data:%p\n", &_end, p, ppp1, ppp0 ); sleep(10000); /* sleep to give chance to look at the process memory map */ return 0; }