Elliot Chance
Elliot Chance

Reputation: 5736

Do not allow malloc()?

I have a makefile that builds, runs unit tests, memory leaks etc. But is there a way I can stop malloc(), free(), calloc() and the like from being used in the source code?

I have replacement memory functions that handle things like mocking. Is there a way I can enforce EagleMemory_Free() to be used instead of free(), for example.

My replacement functions have a different signature so I can't simply create a macro that points the internal one to my own:

void* EagleMemory_Allocate(char *id, size_t size);
void EagleMemory_Free(void *ptr);
void** EagleMemory_MultiAllocate(char *id, size_t size, int quantity);
void EagleMemory_MultiFree(void **ptr, int quantity);
void EagleMemory_MockInit(void);
void EagleMemory_Mock(char *id);
void EagleMemory_MockFinish(void);
int EagleMemory_GetMockInvocations(void);

Oh, I should also point out I don't want to replace the function at runtime and cause my software to crash - that's just stupid. I want to catch the use of the std function at build time or through some other script before the software runs.

Upvotes: 1

Views: 205

Answers (4)

Elliot Chance
Elliot Chance

Reputation: 5736

Thanks to Alexey Frunze. The nm command was exactly what I needed. I added this to my makefile:

NM = nm $(OBJS)/*.o -o 2>&1 | grep -v EagleMemory.o | grep -w '_malloc\|_calloc\|_free'

leaks: build_eagle_test
    if [ `$(NM) | wc -l` -gt 0 ]; then \
        echo "\n==> Do not use stdlib memory functions, use EagleMemory functions instead. <=="; \
        $(NM); \
        exit 1; \
    fi

    ...

Works great!

Upvotes: 4

Jelly
Jelly

Reputation: 120

What about defining :

void *malloc(size_t size)
{ 
    return EagleMemory_Malloc(size);
}

and so on...

Edit :

I give you the power of variadic arguments with this brand new version, it may be overkill but your "different signature" deserves the best !

#define malloc(...) EagleMemory_Malloc(__VA_ARGS__)

Upvotes: 0

Keith Thompson
Keith Thompson

Reputation: 263197

A partial solution would be to compile everything with:

 -Dmalloc=@ERROR -Dfree=@ERROR

(and probably likewise for calloc and realloc). This won't enforce the replacement of malloc by EagleMemory_Malloc, but it will cause any call to malloc to fail to compile.

(I picked @ERROR because it can't occur in legal C source.)

Note that there may still be indirect calls to malloc and friends; for example, strdup() calls malloc(). (strdup is not defined by ISO C, but it's defined by POSIX.)

Upvotes: 2

Vijay
Vijay

Reputation: 67211

use macros:

#define free EagleMemory_Free

Upvotes: 0

Related Questions