【问题标题】:Custom deallocator with an std::vector doesn't get called不会调用带有 std::vector 的自定义释放器
【发布时间】:2018-08-10 04:15:39
【问题描述】:

我希望这段代码在内存被释放时打印“Hello world”-“Hello”,在main 中打印“world”。但是“Hello”永远不会被打印出来,这意味着我的释放器不会被调用。实现它的正确方法是什么?

#include <iostream>
#include <vector>

class MyAllocator : public std::allocator<uint8_t>
{
public:
  void deallocate(uint8_t* data, std::size_t size)
  {
    std::cout << "Hello ";
    std::allocator<uint8_t>::deallocate(data, size);
  }
};


int main()
{
  {
    std::vector<uint8_t, MyAllocator> v(100);
  }
  std::cout << "world\n";

  return 0;
}

我假设它只是调用默认的 std::allocator&lt;uint8_t&gt;::deallocate() 函数,但我没有看到阻止它并让它调用我的函数的方法。

【问题讨论】:

  • 尽量不要说“不起作用”,这不是一个有意义的诊断。我已调整标题以更好地反映您的问题。
  • 我认为制作自定义分配器比这更复杂,即stackoverflow.com/questions/21081796/…
  • 我并没有真正看到他们的分配器和我的分配器之间的概念差异。当然,他们定义了模板和更多构造函数,但是如果 std::vector 需要调用我的类缺少的东西,它就不会编译。我错过了什么?

标签: c++ allocation allocator


【解决方案1】:

事实上,如果你定义了重新绑定,你的分配器就会起作用:

#include <iostream>
#include <vector>

class MyAllocator : public std::allocator<uint8_t>
{
public:

    template <typename U>
    struct rebind
    {
        typedef MyAllocator other;
    };

    void deallocate(uint8_t* data, std::size_t size)
    {
        std::cout << "Hello ";
        std::allocator<uint8_t>::deallocate(data, size);
    }
};


int main()
{
  {
    std::vector<uint8_t, MyAllocator> v(100);
  }
  std::cout << "world\n";

  return 0;
}

生产:

世界你好

【讨论】:

  • 适用于 gcc,但在 VS 中出现错误:Error C2664 'void std::_Deallocate_plain&lt;MyAllocator,0&gt;(_Alloc &amp;,unsigned char *const )': cannot convert argument 2 from 'std::_Container_proxy *' to 'unsigned char *const ' HelloTest c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.12.25827\include\vector 557
  • 它与 VS 2017 / ISO C++17 标准编译得很好。 (\std::c++17)
【解决方案2】:

std::allocator 定义成员 template rebind&lt;U&gt;

并且std::vector 正确使用它来确保它分配正确的内存块,具有适当的大小和对齐方式,因此即使您传递了自定义分配器,重新绑定也会导致实际使用标准分配器。

请参阅 http://en.cppreference.com/w/cpp/concept/Allocator 以了解分配器的潜在成员。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-19
    • 2012-06-26
    • 2019-12-19
    • 2018-07-06
    • 2012-08-07
    • 1970-01-01
    • 2019-11-14
    • 2011-08-30
    相关资源
    最近更新 更多