基于C的malloc()与free()自定义C++容器的内存分配器allocator

参考C++ named requirements: Allocator - cppreference.com

自定义的内存分配器类要实现

T* allocate(std::size_t n)与
void deallocate(T* p, std::size_t n)

两个方法,详见:

代码part1:

#include <cstdlib>
#include <new>
#include <limits>
#include <iostream>
#include <vector>
using namespace std;
class Mtype{
    public:
    int value;
    Mtype():value(-1){                          // 默认构造函数
        cout<<"calling default Mtype()"<<endl;
    }
    Mtype(int val):value(val){                  // 自定义构造函数
        cout<<"calling Mtype(int)"<<endl;
    }
    Mtype(const Mtype &obj):value(obj.value){   // 拷贝构造函数
        cout<<"calling Mtype(const Mtype &obj)"<<endl;
    }
    Mtype & operator=(const Mtype &obj){        // 拷贝赋值运算符函数
        value = obj.value;
        cout<<"calling Mtype &operator=(const Mtype &obj)"<<endl;
        return *this;
    }
    Mtype(Mtype &&obj):value(obj.value){        // 移动构造函数
        cout<<"calling Mtype(Mtype &&obj)"<<endl;
    }
    Mtype & operator=(Mtype &&obj){             // 移动赋值运算符函数
        value = obj.value;
        cout<<"calling Mtype &operator=(Mtype &&obj)"<<endl;
        return *this;
    }
};

part2:


template<class T>
struct Mallocator   // 自定义用于容器的内存分配器类
{
    typedef T value_type;
 
    Mallocator () = default;
    template <class U>
    constexpr Mallocator (const Mallocator <U>&) noexcept { // 拷贝构造
        U obju;
        cout<<"typeid(obju).name() "<<typeid(obju).name()<<endl;
        T objt;
        cout<<"typeid(objt).name() "<<typeid(objt).name()<<endl;

        cout<<"calling Mallocator (const Mallocator <U>&) {}"<<endl;
    }
 
    [[nodiscard]] T* allocate(std::size_t n)
    {
        if (n > std::numeric_limits<std::size_t>::max() / sizeof(T))
            throw std::bad_array_new_length();
 
        if (auto p = static_cast<T*>(std::malloc(n * sizeof(T))))
        {
            report(p, n);
            return p;
        }
 
        throw std::bad_alloc();
    }
 
    void deallocate(T* p, std::size_t n) noexcept
    {
        report(p, n, 0);
        std::free(p);
    }
 
private:
    void report(T* p, std::size_t n, bool alloc = true) const
    {
        std::cout << (alloc ? "Alloc: " : "Dealloc: ") << sizeof(T) * n
                  << " bytes at " << std::hex << std::showbase
                  << reinterpret_cast<void*>(p) << std::dec << '\n';
    }
};

part3:


template<class T, class U>
bool operator==(const Mallocator <T>&, const Mallocator <U>&) { 
    cout<<"calling operator==()"<<endl;
    return true; 
}

template<class T, class U>
bool operator!=(const Mallocator <T>&, const Mallocator <U>&) { 
    cout<<"calling operator!=()"<<endl;
    return false; 
}
void check_Mallocator(){
    cout<<"breakpoint -1"<<endl;
    Mallocator<int> obj;    // 调用默认构造函数
    Mallocator<size_t> obj2(obj);   // 调用拷贝构造函数
    cout<<"sizeof(Mtype) "<<sizeof(Mtype)<<endl;    // 4,只一个虚函数表指针
    std::vector<Mtype, Mallocator<Mtype> > v(2);    // 首先申请8/4=2初始容量的内存,然后调用两次默认构造生成元素
    v.push_back(42);    /* 首先按照逻辑顺序调用一次自定义构造,然后2倍扩容申请16/4=4容量的内存,
    然后对push_back()的右值调用移动构造,然后对旧容器的2个元素调用拷贝构造,然后释放旧容器的8/4=2个元素的内存,*/
    cout<<"breakpoint 1"<<endl;
    // 最后释放16/4=4容量的新容器的内存
}
void check_constructor(){
    Mtype obj;                    // 默认构造
    Mtype obj2(obj);              // 拷贝构造,calling Mtype(const Mtype &obj)
    obj2 = obj;                   // 拷贝赋值,calling Mtype &operator=(const Mtype &obj)
    Mtype obj3(std::move(obj));   // 移动构造,calling Mtype(Mtype &&obj)
    obj3 = std::move(obj2);       // 移动赋值,calling Mtype &operator=(Mtype &&obj)
}
int main()
{
    // check_Mallocator();
    check_constructor();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值