calloc, malloc, free and realloc wrappers to store the size being allocated I'm currently building a node.js addon for libcurl. Right now I'm trying to correctly use v8::Isolate::GetCurrent()-&gt;AdjustAmountOfExternalAllocatedMemory to update v8 on the amount of memory being allocated by libcurl, and to do that I need to wrap the above mentioned functions that libcurl uses, using curl_global_init_mem().

I saw the following code being used here that basically does the same thing, but for another lib.

I currently have the following code (almost identical to the one above):

struct MemWrapper {
    size_t size;
    double data;
};

#define MEMWRAPPER_SIZE offsetof( MemWrapper, data )

inline void* MemWrapperToClient( MemWrapper* memWrapper ) {
    return static_cast&lt;void*&gt;( reinterpret_cast&lt;char*&gt;( memWrapper ) + MEMWRAPPER_SIZE );
}

inline MemWrapper* ClientToMemWrapper( void* client ) {
    return reinterpret_cast&lt;MemWrapper*&gt;( static_cast&lt;char*&gt;( client ) - MEMWRAPPER_SIZE );
}

void AdjustMem( ssize_t diff )
{
    Nan::AdjustExternalMemory( static_cast&lt;int&gt;( diff ) );
}

void* MallocCallback( size_t size )
{
    size_t totalSize = size + MEMWRAPPER_SIZE;
    MemWrapper* mem = static_cast&lt;MemWrapper*&gt;( malloc( totalSize ) );
    if ( !mem ) return NULL;
    mem-&gt;size = size;
    AdjustMem( totalSize );
    return MemWrapperToClient( mem );
}

void FreeCallback( void* p )
{
    if ( !p ) return;
    MemWrapper* mem = ClientToMemWrapper( p );
    ssize_t totalSize = mem-&gt;size + MEMWRAPPER_SIZE;
    AdjustMem( -totalSize );
    free( mem );
}

void* ReallocCallback( void* ptr, size_t size )
{
    if ( !ptr ) return MallocCallback( size );
    MemWrapper* mem1 = ClientToMemWrapper( ptr );
    ssize_t oldSize = mem1-&gt;size;
    MemWrapper* mem2 = static_cast&lt;MemWrapper*&gt;( realloc( mem1, size + MEMWRAPPER_SIZE ) );
    if ( !mem2 ) return NULL;
    mem2-&gt;size = size;
    AdjustMem( ssize_t( size ) - oldSize );
    return MemWrapperToClient( mem2 );
}

char* StrdupCallback( const char* str )
{
    size_t size = strlen( str ) + 1;
    char* res = static_cast&lt;char*&gt;( MallocCallback( size ) );
    if ( res ) memcpy( res, str, size );
    return res;
}

void* CallocCallback( size_t nmemb, size_t size )
{
    size_t totalSize = size + MEMWRAPPER_SIZE;
    MemWrapper* mem = static_cast&lt;MemWrapper*&gt;( calloc( nmemb, totalSize ) );
    if ( !mem ) return NULL;
    mem-&gt;size = nmemb * size;
    AdjustMem( nmemb * totalSize );
    return MemWrapperToClient( mem );
}


I hook it up with libcurl calling:

curl_global_init_mem( CURL_GLOBAL_ALL, MallocCallback, FreeCallback, ReallocCallback, StrdupCallback, CallocCallback );


I compiled the add-on, and from what I can see, it's working fine, but as I'm unexperienced with C++, I need to know if this is correct. What kind of bad things can happen from modifying the pointer returned by calloc, malloc and prealloc like that? Is there any way to improve it?
Check alignment.


I don;t believe you are correctly aligning your objects.

2. Realloc is wrong.

if realloc returns NULL the original pointer is not deallocated.

MemWrapper* mem2 = static_cast&lt;MemWrapper*&gt;( realloc( mem1, size + MEMWRAPPER_SIZE ) );
if ( !mem2 ) return NULL;


Here if realloc fails you have just leaked memory (as mem1 is still valid).

The standard usage pattern for realloc is:

 void* data = malloc(size);
 ...

 void* extra = realloc(data, newSize);
 if (extra) {
     data = extra;   // only reset data if the realloc worked.

 }