string allocator

之前客户报内存频繁malloc, free

用了内存池重载class new,但是string使用没搞定allocator,导致使用了char数组workaround, 最近发现很简单

typedef std::basic_string<char, std::char_traits<char>, mlallocator<char>> mlstring;

只要重写mlallocator就行:

#include "ml_mt_allocator.h"

template <typename T>
class mlallocator
{
public:
    typedef std::size_t    size_type;
    typedef std::ptrdiff_t difference_type;
    typedef T*             pointer;
    typedef const T*       const_pointer;
    typedef T&             reference;
    typedef const T&       const_reference;
    typedef T              value_type;

    mlallocator()noexcept{}
    mlallocator(const mlallocator&)noexcept{}
    template <typename U>
    mlallocator(const mlallocator<U>&)noexcept{}
    ~mlallocator()noexcept{}

    // bigger than 4G fail
    T* allocate(std::size_t num, const void* hint = 0)
    {
        return get_mt_allocator<T>().allocate(num*sizeof(T));
    }

    void deallocate(T* p, std::size_t num)
    {
        get_mt_allocator<T>().deallocate(p, num);
    }

    T* address(T& value)const
    {
        return &value;
    }

    const T* address(const T& value)const
    {
        return &value;

 }

    std::size_t max_size()const noexcept
    {
       return std::numeric_limits<std::size_t>::max()/sizeof(T);
    }

    void construct(T* p, const T& value)
    {
        ::new((void*)p)T(value);
    }

    void destroy(T* p)
    {
        p->~T();
    }

    template <typename U>
    struct rebind
    {
        typedef mlallocator<U> other;
    };
};

template <typename T1, typename T2>
bool operator == (const mlallocator<T1>&, const mlallocator<T2>&)noexcept
{
    return true;
}

template <typename T1, typename T2>
bool operator != (const mlallocator<T1>&, const mlallocator<T2>&)noexcept
{
    return false;
}
 

"ml_mt_allocator.h"即是多线程内存池的ext gnu版本封装

<think>好的,我现在需要帮助用户理解C++中allocator的实现细节以及如何自定义实现一个allocator。根据用户的问题,他们可能已经对allocator的基本用法有所了解,现在想深入其内部机制,并尝试自己实现一个。 首先,我需要回顾用户提供的引用内容,看看有哪些相关信息。引用[1]展示了使用std::allocator分配和释放内存的基本示例,引用[3]和[4]提到了空间配置器的底层实现,包括construct方法使用可变参数模板和完美转发,以及SGI-STL的一级配置器使用malloc和free。用户可能希望了解这些底层细节,比如如何管理内存、构造和销毁对象,以及如何优化内存分配。 接下来,我需要解释allocator的核心职责:内存分配与释放、对象构造与销毁。可能还需要对比标准allocator的实现和自定义的例子,比如基于malloc/free的简单实现。同时,用户可能对如何实现类似STL容器的内存管理感兴趣,例如如何处理异常安全、内存扩展等问题。 在自定义allocator示例部分,我需要确保代码示例清晰,展示allocate、deallocate、construct、destroy等必要方法。特别是construct方法中使用placement new和完美转发,这是关键点。此外,需要说明自定义allocator时需要注意的模板参数和类型定义,如value_type、pointer等。 用户的问题还可能涉及到性能优化,比如引用[4]提到的SGI-STL的一级和二级配置器,这里可能需要简要提及内存池的概念,但根据当前引用,用户可能更关注基础实现,所以保持示例简单明了。 最后,生成的相关问题需要覆盖实现中的关键点,如内存对齐、与STL容器的集成、性能对比、异常处理等,确保用户能进一步探索相关主题。</think>### C++ Allocator实现细节及自定义示例 #### 一、Allocator核心实现机制 1. **内存分配与对象构造分离** Allocator通过`allocate()`分配未初始化的原始内存,再通过`construct()`进行对象构造。这种分离机制允许更灵活的内存管理,例如: ```cpp // 分配内存 T* p = alloc.allocate(1); // 构造对象 alloc.construct(p, args...); // 使用placement new ``` 2. **销毁与释放分离机制** 必须显式调用`destroy()`析构对象后再调用`deallocate()`释放内存: ```cpp alloc.destroy(p); // 调用析构函数 alloc.deallocate(p, 1); // 释放内存 ``` 3. **类型萃取与模板技术** 标准实现通过`std::allocator_traits`获取类型信息: ```cpp using value_type = T; using pointer = T*; using size_type = size_t; ``` 4. **SGI-STL二级配置器**(内存池优化) 采用16个自由链表管理不同大小的内存块,显著减少malloc调用次数[^4]。 #### 二、自定义Allocator示例 ```cpp #include <iostream> #include <memory> template <typename T> class SimpleAllocator { public: using value_type = T; using pointer = T*; using size_type = size_t; // 内存分配 pointer allocate(size_type n) { std::cout << "Allocating " << n << " objects\n"; return static_cast<pointer>(::operator new(n * sizeof(T))); } // 内存释放 void deallocate(pointer p, size_type n) { std::cout << "Deallocating " << n << " objects\n"; ::operator delete(p); } // 对象构造(完美转发) template <typename U, typename... Args> void construct(U* p, Args&&... args) { new (p) U(std::forward<Args>(args)...); } // 对象销毁 template <typename U> void destroy(U* p) { p->~U(); } }; // 验证自定义分配器 int main() { SimpleAllocator<std::string> alloc; auto p = alloc.allocate(2); // 分配两个string的内存 alloc.construct(p, "Hello"); // 构造第一个对象 alloc.construct(p+1, "World"); // 构造第二个对象 std::cout << p[0] << " " << p[1] << std::endl; alloc.destroy(p); // 析构第一个对象 alloc.destroy(p+1); // 析构第二个对象 alloc.deallocate(p, 2); // 释放内存 } ``` #### 三、关键实现细节说明 1. **placement new技术** `construct()`方法通过`new (p) T(args...)`在已分配内存上构造对象,这是allocator的核心技术[^3] 2. **完美转发机制** 使用`std::forward<Args>(args)...`保持参数的值类别(左值/右值),实现高效参数传递[^3] 3. **类型安全保证** 通过模板特化确保分配器仅处理指定类型: ```cpp template <typename U> struct rebind { // STL容器需要的类型转换 using other = SimpleAllocator<U>; }; ``` 4. **内存对齐处理** 标准allocator会自动处理内存对齐问题,自定义实现需特别注意: ```cpp // C++17后推荐使用aligned_alloc void* mem = std::aligned_alloc(alignof(T), size); ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值