calloc / malloc, обернутый std::shared_ptr

У меня есть код, который содержит самодельную хеш-таблицу, использующую 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 больше не сообщает об утечках памяти и ошибках.


person Andreas W. Wylach    schedule 02.03.2013    source источник
comment
pool_alloc должно быть разрешено выделять память только один раз, иначе у вас будет утечка памяти. Или, конечно, отслеживать все выполненные malloc вызовы.   -  person Some programmer dude    schedule 02.03.2013
comment
@JoachimPileborg: pool_alloc вызывается несколько раз (об этом заявил автор кода), потому что указатели в какой-то момент кода просто перезаписываются. Я уже знаю об этой проблеме и также изменю ее.   -  person Andreas W. Wylach    schedule 02.03.2013


Ответы (1)


ОП пишет:

Я написал простой класс пула памяти для своей задачи, поэтому все указатели уничтожаются автоматически. Обернутый calloc() в shared_ptr, похоже, работает нормально и работает, как и ожидалось. Valgrind больше не сообщает об утечках памяти и ошибках.

Другими словами, изменение кода исправило ошибки. :) Этот вопрос можно смело удалить на данный момент.

person Quuxplusone    schedule 31.12.2014