HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

calloc, malloc, free and realloc wrappers to store the size being allocated

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thefreesizeandstorecallocwrappersbeingreallocmalloc

Problem

I'm currently building a node.js addon for libcurl. Right now I'm trying to correctly use v8::Isolate::GetCurrent()->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( reinterpret_cast( memWrapper ) + MEMWRAPPER_SIZE );
}

inline MemWrapper ClientToMemWrapper( void client ) {
return reinterpret_cast( static_cast( client ) - MEMWRAPPER_SIZE );
}

void AdjustMem( ssize_t diff )
{
Nan::AdjustExternalMemory( static_cast( diff ) );
}

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

void FreeCallback( void* p )
{
if ( !p ) return;
MemWrapper* mem = ClientToMemWrapper( p );
ssize_t totalSize = mem->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->size;
MemWrapper* mem2 = static_cast( realloc( mem1, size + MEMWRAPPER_SIZE ) );
if ( !mem2 ) return NULL;
mem2->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( MallocCallback( size ) );
if ( res ) memc

Solution


  • Check alignment.



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

  1. Realloc is wrong.



if realloc returns NULL the original pointer is not deallocated.

MemWrapper* mem2 = static_cast( 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.

 }

Code Snippets

MemWrapper* mem2 = static_cast<MemWrapper*>( realloc( mem1, size + MEMWRAPPER_SIZE ) );
if ( !mem2 ) return NULL;
void* data = malloc(size);
 ...

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

 }

Context

StackExchange Code Review Q#128547, answer score: 2

Revisions (0)

No revisions yet.