为std :: map清除boost :: pool_allocator不会返回VS2017中的整个池

时间:2018-05-25 12:25:28

标签: c++ visual-studio boost pool stdmap

当我在VS2017中运行下一个代码时:

#include <boost/pool/pool_alloc.hpp>
#include <map>
#include <iostream>

int main()
{
    using Map = std::map<int, int, std::less<int>, boost::pool_allocator<std::pair<const int, int>>>;
    using Pool = boost::singleton_pool<boost::pool_allocator_tag, sizeof(Map)>;

    Map temp;

    for (int i = 1; i < 5; i++) temp[i] = i;

    std::cout << "First addresses:\n";
    for (auto& kv : temp) std::cout << &kv.second << "\n";

    temp.clear();
    Pool::purge_memory();

    Map temp2;

    for (int i = 1; i < 5; i++) temp2[i] = i;

    std::cout << "Second addresses:\n";
    for (auto& kv : temp2) std::cout << &kv.second << "\n";

    temp2.clear();
    Pool::purge_memory();

    return 0;
}

我得到了输出:

First addresses:
02A108F4
02A1090C
02A10924
02A1093C
Second addresses:
02A1090C
02A10924
02A1093C
02A10954

Live example

这种行为似乎不正确:地址02A108F4发生了什么?它似乎在清除期间没有返回池中。

当我使用std::vector而不是std::map时,不会发生这种情况。 gcc似乎也正确地返回了内存:Live example

这是VS2017中的错误吗?

1 个答案:

答案 0 :(得分:2)

您正在考虑有关池的实施细节的事情。你很可能是有损失的,但你不能从你看到的分配模式中得出结论。

此外,您正在清除与sizeof(int)关联的池分配器的内存。但是,value_type已经是std::pair<int const, int>,这使得map实现分配了一个未指定的节点类型。

  

哦,你的分配器工作的原因完全一样:容器实现知道你不可能提供正确类型的分配器,因为分配的类型是未指定的。因此它始终是rebind to get the required type

所以,至少要做到这一点

<强> Live On Rextester

#include <boost/pool/pool_alloc.hpp>
#include <map>
#include <iostream>

using Map = std::map<int, int, std::less<int>, boost::pool_allocator<int>>;
using Pool = boost::singleton_pool<boost::pool_allocator_tag, sizeof(Map::value_type)>;

void foo() {
    Map temp;

    for (int i = 1; i < 5; i++) temp[i] = i;

    std::cout << "First addresses:\n";
    for (auto& kv : temp) std::cout << &kv.second << "\n";
}

int main()
{
    foo();
    Pool::purge_memory();

    foo();
    Pool::purge_memory();
}

但是,这仍然是假设实现细节。我认为 c ++ 17为您提供了更多信息(http://en.cppreference.com/w/cpp/container/node_handle)或者您可以看到Boost Container有相关详细信息:https://www.boost.org/doc/libs/1_51_0/doc/html/boost/container/map.html#id463544-bb