У меня есть некоторый код, который содержит самодельные хеш-таблицы с использованием calloc и malloc для выделения памяти. Я хотел бы изменить эти части, используя shared_ptr с пользовательским средством удаления, которое автоматически освобождает выделенную память.
Код является частью китайского алгоритма сегментирования mmseg, он отлично работает, но такой беспорядок, который оставляет утечки памяти. Я подумываю переписать этот код, используя unordered_map или что-то подобное, но сейчас я хотел бы внести эти изменения.
Я читаю ответы на похожие вопросы, такие как shared_ptr с malloc и бесплатно или же Доступ к данным calloc’d через shared_ptr, но у меня есть проблемы, чтобы использовать это в коде ниже.
У меня есть эти строки, где я не могу обернуть вызовы с помощью умного указателя. Так что, может быть, кто-нибудь может помочь мне с этим:
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);
Вышеупомянутый вызов calloc, я бы передал общий указатель с результатом calloc, такой как
std::shared_ptr<Entry *> binsPtr(new_bins, freePtr());
Я не уверен, если это правильно.
mmseg использует процедуру выделения пула с помощью malloc (), которая выглядит следующим образом:
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;
}
Распределитель тогда называется так:
Entry *entry = bins[h];
...
entry = static_cast<Entry *>(pool_alloc(sizeof(Entry)));
entry->word = word;
entry->next = NULL;
bins[h] = entry;
Можно ли изменить подпрограмму pool_alloc так, чтобы я мог обернуть malloc () с помощью общего указателя, определить пользовательское средство удаления (возможно, даже пропустить полную функцию pool_alloc и просто использовать shared_ptr), что-то вроде
std::shared_ptr<Entry> entry((Entry *)malloc(sizeof(Entry)), freePtr());
struct freePtr {
void operator()(void* x) {
free(x);
}
};
Было бы здорово, если бы кто-то мог помочь мне в этом. Заранее спасибо!
Обновить:
Я написал для своей задачи простой класс пула памяти, поэтому все указатели уничтожаются автоматически. Обернутый calloc () в shared_ptr, кажется, работает нормально и работает как положено. Valgrind сообщает, что больше нет утечек памяти и ошибок.
ОП пишет:
Я написал для своей задачи простой класс пула памяти, поэтому все указатели уничтожаются автоматически. Обернутый calloc () в shared_ptr, кажется, работает нормально и работает как положено. Valgrind сообщает, что больше нет утечек памяти и ошибок.
Другими словами, изменение кода исправило ошибки. 🙂 Этот вопрос можно смело удалить на этом этапе.
Других решений пока нет …