Using below code I’m trying to write a wrapper for calloc() so that I can keep trace of allocated heap memory by storing the size in 1st 2/4bytes of the allocated memory. When I tested this alone seems its okay. But when I replace this as my system calloc() then its creating problems.. means some times its returning NULL, even though lot of heap available.
I’m running this on ARM board using IAR compiler:
void *MyCalloc(size_t size) {
size_t new_size = ((size + 3) & ~0x3);
size_t *result = calloc(1,new_size + sizeof(size_t));
if ( result ) {
printf("MyCalloc addr: %p\n", result);
*result = (new_size + sizeof(size_t));
result = result + sizeof(size_t);
}
return result;
}
Any idea why this is causing problem?
There are several problems with your code:
When writing heap functions, or heap wrappers, just don’t use pointer arithmetic for storing heap headers. Use structures. That’s what they’re for.
You’ve introduced a number of integer overflow bugs into your code. If someone asks your
calloc()for 0xfffffffe bytes, you’ll return them 4 bytes. If they write more than 4 bytes to that allocation, there’ll be a heap overflow.Your
calloc()doesn’t have the same signature ascalloc(). Depending on how you’re swapping outcalloc(), this is likely to become a problem.calloc()andmalloc()naturally return aligned pointers. In x86 they need to return a pointer to the application that is aligned to at least 8 bytes, and in x64 they need to return a pointer that is at least 16-byte aligned.In your code, you’re using the real calloc to do the "heavy lifting" (i.e. as the "raw allocator"), which is fine and that will return an 8 or 16-byte aligned pointer, but when you return a pointer 4-bytes into that structure, your calloc ends up returning a non-aligned pointer to the caller, which is likely to cause problems to people calling your calloc replacement.
Try some code a bit more like this: