【问题标题】:calloc / malloc wrapped by std::shared_ptr由 std::shared_ptr 包裹的 calloc / malloc
【发布时间】:2013-02-16 23:20:16
【问题描述】:

我有一些代码包含使用 calloc 和 malloc 进行内存分配的自制哈希表。我想使用带有自定义删除器的 shared_ptr 修改这些部分,该删除器会自动释放分配的内存。 该代码是 mmseg 中文分段器算法的一部分,它运行良好,但由于它留下内存泄漏而变得如此混乱。我正在考虑使用 unordered_map 等重写该代码,但现在我想做这些更改。

我阅读了类似问题的答案,例如shared_ptr with malloc and freeAccessing calloc'd data through a 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 fct 并只使用 shared_ptr),类似于

std::shared_ptr<Entry> entry((Entry *)malloc(sizeof(Entry)), freePtr());

struct freePtr {
    void operator()(void* x) {
        free(x); 
    }
};

如果有人可以帮助我解决这个问题,那就太好了。提前致谢!

更新:

我为我的问题编写了一个简单的内存池类,因此所有指针都会自动销毁。 shared_ptr 中的包装 calloc() 似乎工作正常并且按预期工作。 Valgrind 不再报告内存泄漏和错误。

【问题讨论】:

  • pool_alloc 应该只被允许分配一次内存,否则你将在那里发生内存泄漏。或者当然要跟踪所有完成的malloc 呼叫。
  • @JoachimPileborg: pool_alloc 被多次调用(代码作者声明了这一点),因为代码中某个点的指针被简单地覆盖了。我已经知道这个问题,也会改变它。

标签: c++ malloc smart-pointers calloc


【解决方案1】:

OP 写道:

我为我的问题编写了一个简单的内存池类,因此所有指针都会自动销毁。 shared_ptr 中的包装 calloc() 似乎工作正常并且按预期工作。 Valgrind 不再报告内存泄漏和错误。

换句话说,更改代码修复了错误。 :) 此时可以安全地删除此问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-02
    • 2021-05-23
    • 2017-07-20
    • 2010-12-05
    • 2017-05-06
    • 2020-04-08
    • 2013-11-17
    相关资源
    最近更新 更多