patterncppMinor
calloc, malloc, free and realloc wrappers to store the size being allocated
Viewed 0 times
thefreesizeandstorecallocwrappersbeingreallocmalloc
Problem
I'm currently building a node.js addon for libcurl. Right now I'm trying to correctly use
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
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.
- 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.