具有STL向量的自定义分配器(在Visual Studio工具链内)

时间:2018-09-21 03:34:01

标签: c++ vector stl allocator

在STL向量中使用自定义分配器时(在Visual Studio工具链中),构造函数被调用3次,析构函数被调用4次。我想念什么?以下是代码及其输出:

#include <iostream>
#include <stdlib.h>
#include <new>
#include <memory> 
#include <vector>

using namespace std;

template <class T>
struct Mallocator
{
    typedef T value_type;
    Mallocator() noexcept { cout << "Mallocator() " << this << endl; }
    ~Mallocator() noexcept { cout << "~Mallocator() " << this << endl; }

    template<class U> Mallocator(const Mallocator<U>&) noexcept { cout << "Mallocator(const Mallocator<U>&) " << this << endl; }
    template<class U> Mallocator(Mallocator<U>&&) noexcept { cout << "Mallocator(Mallocator<U>&&) " << this << endl; }

    template<class U> bool operator==(const Mallocator<U>&) const noexcept
    {
        return true;
    }
    template<class U> bool operator!=(const Mallocator<U>&) const noexcept
    {
        return false;
    }
    T* allocate(const size_t n) const;
    void deallocate(T* const p, size_t) const noexcept;
};

template <class T>
T* Mallocator<T>::allocate(const size_t n) const
{
    cout << "   allocate from" << this << endl;
    if (n == 0)
    {
        return nullptr;
    }
    if (n > static_cast<size_t>(-1) / sizeof(T))
    {
        throw std::bad_array_new_length();
    }
    void* const pv = malloc(n * sizeof(T));
    if (!pv) { throw std::bad_alloc(); }
    return static_cast<T*>(pv);
}

template<class T>
void Mallocator<T>::deallocate(T * const p, size_t) const noexcept
{
    cout << "   deallocate from" << this << endl;
    free(p);
}

int main()
{
    Mallocator<uint8_t> mall{};
    std::vector<uint8_t, Mallocator<uint8_t>> v(mall);
    return 0;
}

以下是输出:

Mallocator() 0058FDF3
Mallocator(const Mallocator<U>&) 0058FADF
        allocate from0058FADF
~Mallocator() 0058FADF
Mallocator(const Mallocator<U>&) 0058FAF3
        deallocate from0058FAF3
~Mallocator() 0058FAF3
~Mallocator() 0058FDD8
~Mallocator() 0058FDF3

此外,甚至没有使用向量,分配器已经被实例化了3次(可能是析构函数被调用4次的4倍),这与仅将其实例化一次的GCC工具链相比要高得多。

1 个答案:

答案 0 :(得分:0)

我在template <class T> struct Mallocator

中添加了复制并将构造函数移动到您的代码中
Mallocator(const Mallocator&) { cout << "Mallocator&() " << this << endl; }  
Mallocator(const Mallocator&&) { cout << "Mallocator&&() " << this << endl; } 

这是我在GCC 7.1.0中得到的输出:

Mallocator() 0x61fe3f
Mallocator&() 0x61fe20
~Mallocator() 0x61fe20
~Mallocator() 0x61fe3f

这次构造函数和析构函数调用的数量匹配。您也可以在Visual Studio工具链中对此进行测试。