c++ - 分配器如何在 MSVC 中工作?

标签 c++ visual-c++ memory-management

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

分配器.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>;

最佳答案

是的,你很接近。成员 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);
    }

关于c++ - 分配器如何在 MSVC 中工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58864094/

相关文章:

c++ - 在 __asm 中插入注释导致 C2400 错误 (VS2012)

c++ - 堆分配问题

ios - 了解 Swift 的数组实现

python - Python 函数调用后是否仍然使用内存?

c++ - 离散小波变换整数 Daub 5/3 提升问题

java - 如何在 OS X 上正确创建 C++ 对象文件 (.o)?

c++ - Cython PXD 似乎没有用于 PYX 文件

c++ - CUDA双矩阵溢出

visual-c++ - 链接到所有 Visual Studio $ 变量

Java优先级队列实现——内存局部性