Checking if a pointer is allocated memory or not

Solution 1:

You cannot check, except some implementation specific hacks.

Pointers have no information with them other than where they point. The best you can do is say "I know how this particular compiler version allocates memory, so I'll dereference memory, move the pointer back 4 bytes, check the size, makes sure it matches..." and so on. You cannot do it in a standard fashion, since memory allocation is implementation defined. Not to mention they might have not dynamically allocated it at all.

You just have to assume your client knows how to program in C. The only un-solution I can think of would be to allocate the memory yourself and return it, but that's hardly a small change. (It's a larger design change.)

Solution 2:

The below code is what I have used once to check if some pointer tries to access illegal memory. The mechanism is to induce a SIGSEGV. The SEGV signal was redirected to a private function earlier, which uses longjmp to get back to the program. It is kind of a hack but it works.

The code can be improved (use 'sigaction' instead of 'signal' etc), but it is just to give an idea. Also it is portable to other Unix versions, for Windows I am not sure. Note that the SIGSEGV signal should not be used somewhere else in your program.

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <signal.h>

jmp_buf jump;

void segv (int sig)
{
  longjmp (jump, 1); 
}

int memcheck (void *x) 
{
  volatile char c;
  int illegal = 0;

  signal (SIGSEGV, segv);

  if (!setjmp (jump))
    c = *(char *) (x);
  else
    illegal = 1;

  signal (SIGSEGV, SIG_DFL);

  return (illegal);
}

int main (int argc, char *argv[])
{
  int *i, *j; 

  i = malloc (1);

  if (memcheck (i))
    printf ("i points to illegal memory\n");
  if (memcheck (j))
    printf ("j points to illegal memory\n");

  free (i);

  return (0);
}

Solution 3:

For a platform-specific solution, you may be interested in the Win32 function IsBadReadPtr (and others like it). This function will be able to (almost) predict whether you will get a segmentation fault when reading from a particular chunk of memory.

However, this does not protect you in the general case, because the operating system knows nothing of the C runtime heap manager, and if a caller passes in a buffer that isn't as large as you expect, then the rest of the heap block will continue to be readable from an OS perspective.