I have some code that contains a self-made hashtable using calloc and malloc for memory allocation. I would like to modify these parts using a shared_ptr with a custom deleter that frees automatically the allocated memory. The code is part of the mmseg chinese segmenter algorithm, it is working great but is such a mess as it leaves memory leaks. I am considering to rewrite that code using a unordered_map or such, but for now I would like to make these changes.
I read the answers on similar questions, such as shared_ptr with malloc and free or Accessing calloc'd data through a shared_ptr, but I have problems to use that on the code below.
I have these lines where I am not able to wrap the calls with the smart pointer. So maybe somebody can help me out with this:
struct Word {
unsigned char nbytes; /* number of bytes */
char length; /* number of characters */
unsigned short freq;
char text[word_embed_len];
};
struct Entry {
Word *word;
Entry *next;
};
static Entry **new_bins = static_cast<Entry **>(std::calloc(init_size,
sizeof(Entry *)));
Entry *entry, ...;
...
new_bins[hash_val] = entry;
....
free(new_bins);
The above calloc call I would feed shared pointer with the result of calloc, such as
std::shared_ptr<Entry *> binsPtr(new_bins, freePtr());
I am not shure if this is correct.
mmseg uses a pool allocation routine with malloc(), which looks like this:
inline void *pool_alloc(int len) {
void *mem = _pool_base;
if (len <= _pool_size) {
_pool_size -= len;
_pool_base += len;
return mem;
}
_pool_base = static_cast<char *>(std::malloc(REALLOC_SIZE));
mem = _pool_base;
_pool_base += len;
_pool_size = REALLOC_SIZE - len;
return mem;
}
The allocator then is called like this:
Entry *entry = bins[h];
...
entry = static_cast<Entry *>(pool_alloc(sizeof(Entry)));
entry->word = word;
entry->next = NULL;
bins[h] = entry;
Is it possible to modify the pool_alloc routine such as I could wrap the malloc() with a shared pointer an define a custom deleter (maybe even skip the complete pool_alloc fct and just use a shared_ptr), something like
std::shared_ptr<Entry> entry((Entry *)malloc(sizeof(Entry)), freePtr());
struct freePtr {
void operator()(void* x) {
free(x);
}
};
Would be great if somebody could help me out on this. Thanks in advance!
Update:
I coded a simple memory pool class for my problem, so all pointers get destroyed automatically. The wrapped calloc() in the shared_ptr seems to work fine and works as expected. Valgrind reports no more memory leaks and errors.