记录std :: containers的分配器?

gnz*_*lbg 4 c++ memory-management allocator boost-mpl c++11

X:我需要知道我的程序的每个部分使用了多少内存.我的程序使用了很多C++ std库.特别是,我想知道每个对象使用多少内存.

我是怎么做的:记录消费some_vector,只写

my::vector<double,MPLLIBS_STRING("some_vector")> some_vector;
Run Code Online (Sandbox Code Playgroud)

哪里

namespace my {
  template<class T, class S>
  using vector = std::vector<T,LoggingAllocator<T,S>>;
}
Run Code Online (Sandbox Code Playgroud)

loggin分配器实现如下:

template<class T, class S = MPLLIBS_STRING("unknown")> struct LoggingAllocator {
  // ... boilerplate ...

  pointer allocate (size_type n, std::allocator<void>::const_pointer hint = 0) {
    log_allocation(boost::mpl::c_str<S>::value);
    // allocate_memory (I need to handle it myself)
  }
  void destroy (pointer p) ; // logs destruction
  void deallocate (pointer p, size_type num); // logs deallocation
};
Run Code Online (Sandbox Code Playgroud)

问题:是否有更好的方法以通用方式获得此行为?通过更好,我的意思是,更简单,更好,没有依赖boost::mplmpllibs::metaparse,... ...理想情况下,我只想写

my::vector<double,"some_vector"> some_vector;
Run Code Online (Sandbox Code Playgroud)

并完成它.

Som*_*ude 5

虽然可能不是"更通用",但如果您不想自己处理所有分配,则可以继承标准分配器std::allocator:

template<class T, class S = MPLLIBS_STRING("unknown"), class Allocator = std::allocator<T>>
struct LoggingAllocator : public Allocator {
    // ...
};
Run Code Online (Sandbox Code Playgroud)

allocate/ destroy/ deallocate函数中执行日志记录,然后调用parents方法:

pointer allocate (size_type n, std::allocator<void>::const_pointer hint = 0) {
    log_allocation(boost::mpl::c_str<S>::value);
    return Allocator::allocate(n, hint);
}
Run Code Online (Sandbox Code Playgroud)

但是请注意,std::allocator它并非真正设计用于继承,例如它没有虚拟析构函数.

  • 如果你从另一个分配器继承,那么创建一个新版本的'rebind'是至关重要的,这样如果分配器的类型被反弹,它将返回你的分配器,而不是你继承的分配器. (6认同)