gpt4 book ai didi

c++ - 自定义内存堆上的 boost::object_pool

转载 作者:行者123 更新时间:2023-11-28 00:38:55 25 4
gpt4 key购买 nike

我想创建一个对象池,但我希望它只在我的内存堆的特定段上分配内存。有没有办法使用 boost 来做到这一点?

最佳答案

Boost.Pool 的 object_pool允许用户通过提供 UserAllocator 来控制池使用的内存.根据文档:

Pool objects need to request memory blocks from the system, which the Pool then splits into chunks to allocate to the user. By specifying a UserAllocator template parameter to various Pool interfaces, users can control how those system memory blocks are allocated.

Boost.Pool 仅提供使用new/deletemalloc/free 的基本分配器。但是,如果可以编写分配器在空闲存储的特定段进行分配,则也可以将 object_pool 配置为执行此操作。可能需要检查编译器和平台是否支持将免费存储内的分配限制为特定段。


这是一个基本示例,我忽略了一些细节以保持示例简单,并展示了一个类型如何满足 UserAllocator 的要求。在此示例中,boost::object_pool 将使用使用预分配静态内存的自定义分配器。

#include <iostream>
#include <boost/array.hpp>
#include <boost/pool/object_pool.hpp>

namespace detail {

/// @brief Pre-allocated managed memory block.
template <std::size_t N>
class arena
{
public:

/// @brief Constructor.
arena()
: current_(&buffer_.front()), // Set current to start.
end_(current_ + N) // End sentinel.
{
std::cout << "arena memory range: "
<< static_cast<void*>(current_) << " - "
<< static_cast<const void*>(end_) << std::endl;
}

/// @brief Attempt to allocate memory from pre-allocated block.
///
/// @param n Count of bytes to allocate.
///
/// @param Non-zero if allocation is succesfull. Otherwise, zero.
char* allocate(std::size_t n)
{
// If there is no more memory, then return zero.
if ((current_ + n) > end_) return 0;

// Otherwise, return available memory and shift current.
std::cout << "arena allocating: "
<< static_cast<void*>(current_) << std::endl;
char* ptr = current_;
current_ += n;
return ptr;
}

void deallocate(char* p, std::size_t n)
{
// ...
}

private:

/// @brief Block of memory used for allocations.
boost::array<char, N> buffer_;

/// @brief Pointer to current allocation.
char* current_;

//// @brief End pointer sentinel.
const char* end_;
};

} // namespace detail

/// @brief Allocator that meets Boost.Pool's UserAllocator Concepts.
/// This allocator will allocate memory from a pre-allocated
/// block of static memory. Each instance of the template is
/// considered to be its own unique allocator, and thus has its
/// own memory.
template <std::size_t N>
class static_allocator
{
public:
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;

static char* malloc(const size_type n) { return arena_.allocate(n); }
static void free(char* p) { arena_.deallocate(p, 1); }

private:
static detail::arena<N> arena_;
};

template <std::size_t N>
detail::arena<N> static_allocator<N>::arena_;

/// @brief Helper type.
template <typename T, std::size_t N>
struct static_object_pool:
boost::object_pool<T, static_allocator<N * sizeof(T)> >
{};

/// Mockup object.
class Foo {};

int main()
{
static_object_pool<Foo, 128> pool;

Foo* a = pool.malloc();
std::cout << "a is at " << a << std::endl;
Foo* b = pool.malloc();
std::cout << "b is at " << b << " -- freeing b" << std::endl;
pool.free(b);
Foo* c = pool.malloc();
std::cout << "c is at " << c << std::endl;
}

输出:

arena memory range: 0x804b5a0 - 0x804b620
arena allocating: 0x804b5a0
a is at 0x804b5a0
b is at 0x804b5a4 -- freeing b
c is at 0x804b5a4

请注意,从 object_pool::malloc() 返回的每个地址都在 arena 的内存范围内。此外,当 b 通过 pool.free(b) 释放时,内存 (0x804b5a4) 会在下一次 时立即被池重用>malloc() 用于 c

关于c++ - 自定义内存堆上的 boost::object_pool,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19829351/

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