I'm using a library that lets me override some of it's macros for how it allocates to the heap
#define STBI_MALLOC(sz) malloc(sz)
#define STBI_REALLOC(p,newsz) realloc(p,newsz)
#define STBI_FREE(p) free(p)
I'd like to accept some of it's allocated heap into my program without wrapping it or worrying too much about how it's allocated, by making the STBI_FREE()
macro synonymous with how I'd normally deallocate such memory, with a delete [](char*)p
#define STBI_MALLOC(sz) ((void*)new char[sz])
#define STBI_REALLOC(p,newsz) ???
#define STBI_FREE(p) (delete [](char*)(p))
I'm unsure of what to use for STBI_REALLOC()
though. I could do it in multiple lines if I had the previous size, but...
// STBI_REALLOC(p,newsz)
if (newsz <= ???) { // don't know the allocation size
return p;
} else {
char * next = new char[newsz]
memcpy(next, p, ???); // don't know the allocaion size
delete [] (char*)p;
return (void*)next;
}
...without knowing the allocation's size intrinsically, it's not possible with the arguments the macro accepts within the library. Do I have an option here that I can slot into this macro definition?
--- edit ---
(The accepted answer still stands, and this is outside the scope of the original question, but I'm appending this in case anyone using the same library encounters it)
Turns out this library had a hidden section of preprocessor for this exact scenario, where the library will instead use STBI_REALLOC_SIZED(p,oldsz,newsz)
if it's defined by the library user.
which allows me to define for the library the following Absolute Masterpiece:
#define STBI_MALLOC(sz) ((void*)(new char[sz]))
#define STBI_REALLOC_SIZED(p,oldsz,newsz) \
((newsz) <= (oldsz) ? (void*)(p) : [](void* lp, size_t loldsz, size_t lnewsz)->void*{char*n = new char[lnewsz]; memcpy(n, lp, loldsz); delete [] (char*)lp; return (void*)n;}(p, oldsz, newsz))
#define STBI_FREE(p) (delete [](char*)(p))
Or this one works quite well too
#define REALLOC_SIZED(p,oldsz,newsz) \
((newsz) <= (oldsz) ? (void*)(p) : \
memcpy(new char[newsz], (void*)std::unique_ptr<char>((char*)(p)).get(), oldsz))
TL;DR - It can't be done, leave the code as is.
There is no realloc
possibility in C++. realloc
goes against the object-oriented nature of C++, as objects can't be moved around like that, so C++ outright dismissed the idea.
Nor can one be implemented in terms of new
and delete
, as you need to know the current array size to copy the data, which is impossible (in a portable way), not to mention it being inefficient to have to copy stuff around every time (realloc
in many cases works in-place).
The good news is, there is nothing wrong with using malloc
, realloc
and free
for allocating raw memory in a C++ program. Also the built-in new
and delete
in many cases delegate to malloc
and free
, so there is no issue really.