I know this is an old question, but almost everything is possible in C. There are several hacking solutions here, but the correct way to determine if memory is allocated correctly is to use the oracle to replace the place malloc , calloc , realloc and free . Similarly, test environments (e.g. cmocka) can detect memory problems (seg errors, not freeing memory, etc.). You can save the list of memory addresses allocated as they are allocated, and simply check this list when the user wants to use your function. I implemented something very similar for my own testing platform. Code example:
typedef struct memory_ref { void *ptr; int bytes; memory_ref *next; } memory_ref *HEAD = NULL; void *__wrap_malloc(size_t bytes) { if(HEAD == NULL) { HEAD = __real_malloc(sizeof(memory_ref)); } void *tmpPtr = __real_malloc(bytes); memory_ref *previousRef = HEAD; memory_ref *currentRef = HEAD->next; while(current != NULL) { previousRef = currentRef; currentRef = currentRef->next; } memory_ref *newRef = (memory_ref *)__real_malloc(sizeof(memory_ref)); *newRef = (memory_ref){ .ptr = tmpPtr, .bytes = bytes, .next = NULL }; previousRef->next = newRef; return tmpPtr; }
You would have similar functions for calloc , realloc and free , each wrapper with the __wrap_ prefix. Real malloc is available using __real_malloc (similarly for other functions that you wrap). Whenever you want to check if memory is actually allocated, simply go to the linked list memory_ref and find the memory address. If you find it large enough, you know for sure that the memory address will not crash your program; otherwise return an error. In the header file that your program uses, you must add the following lines:
extern void *__real_malloc (size_t); extern void *__wrap_malloc (size_t); extern void *__real_realloc (size_t); extern void *__wrap_realloc (size_t);
My needs were pretty simple, so I implemented a very basic implementation, but you can imagine how it can be expanded to have a better tracking system (for example, create a struct that keeps track of the memory location in addition to size). Then you just compile the code with
gcc src_files -o dest_file -Wl,-wrap,malloc -Wl,-wrap,calloc -Wl,-wrap,realloc -Wl,-wrap,free
The disadvantage is that the user must compile the source code with the above directives; however, this is far from worse than what I saw. There is some overhead for allocating and freeing memory, but when adding security, there is always some overhead.