Я думаю, что синтаксический анализ /proc/self/maps
- единственный надежный способ для Linux найти сегмент кучи.И не забывайте, что некоторые распределители (включая один в моем SLES) действительно используют для больших блоков mmap()
, поэтому память больше не является частью кучи и может находиться в любом случайном месте.
В противном случае, обычноld
добавляет символ, отмечающий конец всех сегментов в эльфе, и этот символ называется _end
.Например:
extern void *_end;
printf( "%p\n", &_end );
Это соответствует концу .bss
, традиционно последнему сегменту эльфа.После адреса, с некоторым выравниванием, обычно следует куча.Stack (s) и mmap () (включая общие библиотеки) находятся по старшим адресам адресного пространства.
Я не уверен, насколько он переносим, но, очевидно, он работает аналогично в Solaris10. В 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;
}