Here is an example:
typedef struct _BlockHeader {
int Size;
} BlockHeader;
void *MyMalloc(int size) {
char *ptr = malloc(size + sizeof(BlockHeader));
BlockHeader *hdr = (BlockHeader*)ptr;
hdr->Size = size;
return (ptr + sizeof(BlockHeader));
}
void MyFree(void *ptr) {
char *myptr = (char*)ptr;
free(myptr - sizeof(BlockHeader));
}
int GetPtrMallocedSize(void *ptr) {
char *myptr = (char*)ptr;
BlockHeader *hdr = myptr - sizeof(BlockHeader);
return (hdr->size);
}
Pratically each memory block starts with an header, collecting memory block information. Of course also realloc and calloc shall be implemented, but memory block cannot be used by other software which expect "normal" malloced memory.
Another way to do this is to hash the pointer, and collect memory information by hooking the malloc/free functions.
I know that MS CRT uses this to keep track of heap overflow and memory leaks. I don't know if there are some sideeffect... actually I've never used it.