У меня есть код, который содержит самодельную хеш-таблицу, использующую calloc и malloc для выделения памяти. Я хотел бы изменить эти части, используя shared_ptr с пользовательским средством удаления, которое автоматически освобождает выделенную память. Этот код является частью алгоритма китайского сегментатора mmseg, он отлично работает, но в таком беспорядке, что оставляет утечки памяти. Я собираюсь переписать этот код, используя unordered_map или что-то подобное, но сейчас я хотел бы внести эти изменения.
Я читал ответы на похожие вопросы, такие как shared_ptr с malloc и бесплатно или Доступ к данным calloc через 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() общим указателем и определить настраиваемый модуль удаления (возможно, даже пропустить полный fct 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 больше не сообщает об утечках памяти и ошибках.
pool_alloc
должно быть разрешено выделять память только один раз, иначе у вас будет утечка памяти. Или, конечно, отслеживать все выполненныеmalloc
вызовы. - person Some programmer dude   schedule 02.03.2013pool_alloc
вызывается несколько раз (об этом заявил автор кода), потому что указатели в какой-то момент кода просто перезаписываются. Я уже знаю об этой проблеме и также изменю ее. - person Andreas W. Wylach   schedule 02.03.2013