Warning: This section is extremely system dependent. The ideas should be generally applicable; however, the exact implementations described will need to be tailored to fit your system.
(In general) there are 4 regions of memory:
global
& static
variables are stored.
auto
) variables are stored.
malloc()
memory comes from.
Here, we will consider how to determine the start and the end of the stack and heap, and use that to determine whether a pointer points to a stack location or a heap location.
For now, we will assume that stacks grow downwards (i.e. the stack of a called function has a smaller address than the stack of its calling function). This is true of the majority of all systems. Then:
static void * lcl_start_stack_ptr = 0;
void
setup_stack_ptr(
void * start
)
{
int _top;
/* verify that stacks grow downwards */
assert( ((void*)&_top) < start );
lcl_start_stack_ptr = start;
}
int
is_stack_ptr(
void * ptr
)
{
int _top;
void * top = &_top;
return ptr < lcl_start_stack_ptr && ptr > top;
}
To set up the initial value of lcl_stack_start
, call from main()
with the address of some stack address; on many systems argc
is a good candidate.
int
main(
int argc,
char * argv[]
)
{
/* declarations */
setup_start_ptr(&argc);
/* ... */
}
For the heap, things get a little more complicated; in particular, there is no portable way to determine the current end of the heap. However, on many systems, we sbrk(0)
returns the end of the heap.
In the following code, we assume:
sbrk(0)
returns the end of the heap.
unsigned
is large enough to hold a pointer value.
malloc()
will (in general) return
larger values as more memory gets allocated. (This is true on most systems).
#define ADJUST_HEAP_PTR 0x1000
static void * lcl_start_heap_ptr = 0;
void
setup_heap_ptr( void )
{
unsigned start = (unsigned) sbrk(0);
start -= ADJUST_HEAP_PTR;
lcl_start_heap_ptr = (void *)start;
}
int
is_heap_ptr(
void * ptr
)
{
void * top = sbrk(0);
return ptr >= lcl_start_heap_ptr && ptr <= top;
}
setup_heap_ptr()
should be called from the beginning of main()
.
Unfortunately, it is difficult to find the true start of the heap. Even if setup_heap_ptr()
is the first function called from inside main()
, some allocation has probably already occurred. In general, a system calls various functions prior to calling main()
. These allocate memory, and disturb the true start of the heap. On most systems, it is possible to compensate for this by using ADJUST_HEAP_PTR
.