我可以获取堆结尾的地址sbrk(0),但有没有办法以编程方式获取堆的起始地址,而不是通过解析内容/proc/self/maps?
Dum*_*001 12
我认为解析/proc/self/maps是Linux上唯一可靠的方法来查找堆段.并且不要忘记一些分配器(包括我的SLES中的一个)确实用于大块,mmap()因此内存不再是堆的一部分,并且可以在任何随机位置.
否则,通常ld会在elf中添加一个标记所有段末尾的符号,并调用该符号_end.例如:
extern void *_end;
printf( "%p\n", &_end );
Run Code Online (Sandbox Code Playgroud)
它匹配.bss传统上最后一段精灵的结尾.在地址之后,通过一些对齐,通常在堆之后.Stack(s)和mmap()s(包括共享库)位于地址空间的较高地址.
我不确定它是多么可移植,但显然它在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;
}
Run Code Online (Sandbox Code Playgroud)