分配器如何在MSVC中工作?

问题描述 投票:1回答:1

我已经阅读了https://medium.com/@vgasparyan1995/what-is-an-allocator-c8df15a93ed,他向他解释了分配器的工作原理,但是当我实现以下代码时,它总是给我0个结果。代码和MSVC有什么问题?

Allocator.h

#pragma once

#include <atomic>
#include <memory>
#include <iostream>
#include <vector>
#include <list>
#include <set>


namespace Milad
{
    std::atomic_int GMemoryUsed(0);

    template <typename T>
    class Allocator : public std::allocator<T>
    {
    private:
        using PrBase = std::allocator<T>;
        using PrPointer = typename std::allocator_traits<PrBase>::pointer;
        using PrSizeType = typename std::allocator_traits<PrBase>::size_type;
    public:
        Allocator() = default;

        template <typename U>
        Allocator(const Allocator<U>& arg_other) : PrBase(arg_other)
        {

        }

        template <typename U>
        struct rebind
        {
            using other = Allocator<U>;
        };

        PrPointer Allocate(PrSizeType arg_n)
        {
            GMemoryUsed.fetch_add(arg_n * sizeof(T));
            return PrBase::allocate(arg_n);
        }

        void Deallocate(PrPointer arg_p, PrSizeType arg_sz)
        {
            GMemoryUsed.fetch_sub(arg_sz * sizeof(T));
            PrBase::deallocate(arg_p, arg_sz);
        }
    };
}

Main.cpp

#include "Allocator.h"

template <template <typename T, typename AllocT> typename ContainerT>
void Measurement()
{
    std::cout << __FUNCSIG__ << std::endl;
    std::cout << "Before Memory Usage: " << Milad::GMemoryUsed.load() << std::endl;
    ContainerT<int, Milad::Allocator<int>> Container;
    for (int i = 0; i < 1000; ++i)
    {
        Container.insert(std::end(Container), i);
    }
    std::cout << "After Memory Usage: " << Milad::GMemoryUsed.load() << std::endl;
}

template <typename T, typename AllocT>
using SetWithDefaultComparator = std::set<T, std::less<>, AllocT>;

int main(int argc, const char* argv[])
{
    Measurement<std::vector>();
    Measurement<std::list>();
    Measurement<SetWithDefaultComparator>();

    return 0;
}

当我运行程序时,它给我以下结果:

void __cdecl Measurement<class std::vector>(void)
Before Memory Usage: 0
After Memory Usage: 0
void __cdecl Measurement<class std::list>(void)
Before Memory Usage: 0
After Memory Usage: 0
void __cdecl Measurement<SetWithDefaultComparator>(void)
Before Memory Usage: 0
After Memory Usage: 0

而且,我不明白如何解释以下代码行。为什么这些行是这样实现的:

template <template <typename T, typename AllocT> typename ContainerT>

ContainerT<int, Milad::Allocator<int>> Container;

template <typename T, typename AllocT>
using SetWithDefaultComparator = std::set<T, std::less<>, AllocT>;
c++ visual-c++ memory-management
1个回答
0
投票

是的,你很近。成员allocatedeallocatestd::allocator的成员,并且容器正在寻找这些成员。因为您已大写成员的版本,所以将调用默认分配器,而不会调用内存覆盖。您的代码应为:

    PrPointer allocate(PrSizeType arg_n)
    {
        GMemoryUsed.fetch_add(arg_n * sizeof(T));
        return PrBase::allocate(arg_n);
    }

    void deallocate(PrPointer arg_p, PrSizeType arg_sz)
    {
        GMemoryUsed.fetch_sub(arg_sz * sizeof(T));
        PrBase::deallocate(arg_p, arg_sz);
    }
© www.soinside.com 2019 - 2024. All rights reserved.