简体   繁体   English

MSVC中的C ++自定义STL分配器错误?

[英]C++ Custom STL allocator bug in MSVC?

I think found a bug in MSVC++. 我认为在MSVC ++中发现了一个错误。 Or maybe this is a lack of my knowledge and I missed something in the code. 也许这是我的知识不足,我错过了代码中的某些内容。 I created a custom allocator: 我创建了一个自定义分配器:

#include <forward_list>
#include <iostream>

template <class T>
class Allocator
{
    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;

        template <class U>
        struct rebind
        {
            typedef Allocator<U> other;
        };

        Allocator()
        {
            std::cout << (ptrdiff_t) this << " Allocator()" << std::endl;
        }

        Allocator(const Allocator &allocator)
        {
            std::cout << (ptrdiff_t) this << " Allocator(const Allocator &allocator)" << std::endl;
        }

        template <class U>
        Allocator(const Allocator<U> &other)
        {
            std::cout << (ptrdiff_t) this << " Allocator(const Allocator<U> &other)" << std::endl;
        }

        ~Allocator()
        {
            std::cout << (ptrdiff_t) this << " ~Allocator()" << std::endl;
        }

        pointer allocate(size_type n, std::allocator<void>::const_pointer hint = 0)
        {
            std::cout << (ptrdiff_t) this << " allocate()" << std::endl;
            return (pointer) std::malloc(n * sizeof(T));
        }

        void deallocate(pointer p, size_type n)
        {
            std::cout << (ptrdiff_t) this << " deallocate()" << std::endl;
            std::free(p);
        }

        void construct(pointer p, const_reference val)
        {
            new (p) T(val);
        }

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

When I tried to use it for example this way: 例如,当我尝试以这种方式使用它时:

Allocator<int> allocator;
std::forward_list<int, Allocator<int>> memoryPoolList(allocator);

I got following a output 我得到了一个输出

557863138612 Allocator()
557863138648 Allocator(const Allocator<U> &other)
557863137412 Allocator(const Allocator<U> &other)
557863137412 allocate()
557863137412 ~Allocator()
557863137460 Allocator(const Allocator<U> &other)
557863137460 deallocate()
557863137460 ~Allocator()
557863138648 ~Allocator()
557863138612 ~Allocator()

If you look carefully allocate function is called on different object and deallocate() on another! 如果仔细看一下,分配函数将在另一个对象上调用,而deallocate()将在另一个对象上调用! Moreover why do they perform allocation on empty forward_list? 此外,为什么他们要对空的forward_list执行分配? This behaves this way for other containers too. 这对于其他容器也是如此。 And works pretty well on GCC. 并且在GCC上效果很好。 I'll be thankful for all ideas! 我会为所有想法表示感谢!

EDIT 编辑

I would like to point out that there is completely no problem when I use malloc and free. 我想指出的是,当我使用malloc和free时完全没有问题。 However if my Allocator uses own mechanisms for memory management, you will find that object at address 557863137412 used for allocation is destroyed before creation of object 557863137460 which is used for deallocation. 但是,如果我的分配器使用自己的内存管理机制,则会发现在创建用于释放的对象557863137460之前,已将地址557863137412上用于分配的对象销毁了。 This will simply not work. 这根本行不通。

There is no bug. 没有错误。

If you look carefully allocate function is called on different object and deallocate() on another! 如果仔细看一下, allocate函数将在另一个对象上调用,而deallocate()在另一个对象上调用!

You are printing the address of the allocator, not the memory (de)allocated. 您正在打印分配器的地址,而不是已分配(取消)的内存。 Copies of an allocator are supposed to be able to deallocate memory allocated by one another, and implementations are allowed to copy allocators freely. 分配器的副本应该能够释放彼此分配的内存,并且允许实现自由地复制分配器。 (In particular, in this case it looks like it was rebinding the stored allocator prior to the allocate and deallocate.) (特别是在这种情况下,看起来好像是在分配和取消分配之前重新绑定了存储的分配器。)

Moreover why do they perform allocation on empty forward_list ? 此外,为什么他们要对空的forward_list执行分配?

You only see this when you build in debug mode, which (among other things) activates their iterator debugging machinery. 您只有在以调试模式进行构建时才能看到此信息,调试模式(除其他外)将激活其迭代器调试机制。 That machinery requires additional memory that is allocated on construction of the container and deallocated on destruction of the container. 该机械需要附加的存储器,该附加的存储器在容器的构造上分配并且在容器的破坏时重新分配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM