I am working on legacy code where memory allocation/deallocation done in traditional C style, but want to wrap it in a unique_ptr with a custom deleter. Consider a case where a 2 dimensional array is allocated by legacy code by calling calloc/malloc. I need to call the corresponding legacy deallocator function taking two parameters - pointer to array and size of the array. How to define a custom deleter that takes 2 parameters in this case, both will be passed only at the time of initializing the unique_ptr to take ownership of already allocated array? Thanks in advance.
A simplified(yet contrived) example below:
// function allocates memory and returns size of the buffer
void legacyFunction(char **array, int *num)
{
char *p = (char *)calloc(5, sizeof(char));
for (auto i=0; i<5; i)
{
p[i] = 'a';
}
*num = 5;
*array = p;
return;
}
int main()
{
char *array = nullptr;
int numofElts = 0;
legacyFunction(&array, &numofElts);
// unique_ptr here to take ownership of array
// custom deleter should take both pointer and size
// the size could be any number based on business use case
return 0;
}
CodePudding user response:
The deleter is an object. It can hold onto the size.
struct LegacyDeleter
{
int size;
void operator()(char** ptr) const noexcept
{ legacyDeallocate(ptr, size); }
};
using legacy_ptr = std::unique_ptr<char*, LegacyDeleter>;
int main()
{
legacy_ptr ptr(legacyAllocatorFunction(5), LegacyDeleter{5});
}