gpt4 book ai didi

c++ - 使用分配器替代 malloc()/free()?

转载 作者:太空狗 更新时间:2023-10-29 20:47:07 25 4
gpt4 key购买 nike

是否有任何可移植的方法来将 malloc()/free() 的使用替换为类似 STL 的分配器的包装器?

上下文:我有一个 C 库,它允许为内存管理指定自定义的类似 malloc()/free() 的函数,并且在多线程上下文中使用。寻找一个好的多线程分配器,我发现 GCC-libstdc++ 的 mt_alloc 对我的工作负载表现非常好。现在我想在所说的 C 库中使用它,但是该怎么做呢?

我看到的主要问题是在 deallocate() 函数中,与 free() 相反,除了地址之外,它还获取分配的内存块的大小。所以我需要以某种方式跟踪与每个内存分配相关的大小,以便在释放内存时可以将其反馈给 deallocate() 。我想过的最简单的解决方案是将分配的内存大小存储在内存块的开头,但我不确定如何解决可能出现的对齐问题。

是否有任何我忽略的简单解决方案?

最佳答案

在我的平台上,malloc确保分配的内存在 8 字节边界对齐。要模仿此行为,请使用 allocator<uint64_t> :

#include <stdint.h>
#include <ext/mt_allocator.h>

static __gnu_cxx::__mt_alloc<uint64_t> theAllocator;

void* mtmalloc(size_t size)
{
// Divide size by sizeof(uint64_t) and round up
size_t payloadElementCount = (size + sizeof(uint64_t) - 1) /
sizeof(uint64_t);

// Add an extra uint64_t to store the chunk size
size_t chunkElementCount = 1 + payloadElementCount;

// Allocate the chunk
uint64_t* chunk = theAllocator.allocate(chunkElementCount);

// Store the chunk size in the first word
chunk[0] = chunkElementCount;

// Return a pointer past where the chunk size is stored
return static_cast<void*>(chunk + 1);
}

void mtfree(void* pointer)
{
// The chunk begins one word before the passed in pointer
uint64_t* chunk = static_cast<uint64_t*>(pointer) - 1;

// Retrieve the chunk size
size_t chunkElementCount = chunk[0];

// Deallocate the chunk
theAllocator.deallocate(chunk, chunkElementCount);
}

int main()
{
int* array = (int*)mtmalloc(sizeof(int) * 4);
array[0] = 0;
array[1] = 1;
array[2] = 2;
array[3] = 3;
mtfree(array);
}

对于您的平台,替换为 uint64_t使用适当的类型。

你应该用 Valgrind 之类的东西来测试它以确保没有内存泄漏!


而不是 uint64_t , 你可以使用 GCC 的 __BIGGEST_ALIGNMENT__和 Boost 的 aligned_storage type trait对于可移植到 GCC 编译器的解决方案:

typedef boost::aligned_storage<__BIGGEST_ALIGNMENT__, __BIGGEST_ALIGNMENT__> AlignedType;

关于c++ - 使用分配器替代 malloc()/free()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6402703/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com