Visual Studio中有状态分配器异常?如何编写可用自定义有状态分配器
在Visual Studio中实现可用的自定义有状态分配器
针对VS 17.8.5对有状态分配器的兼容性问题,你可以从以下几个方向调整自定义分配器的实现:
严格对齐C++标准的分配器规范
确保分配器实现所有必要的成员与函数,重点注意:- 显式声明
using is_always_equal = std::false_type,同时正确实现operator==和operator!=,用于判断两个分配器实例是否共享同一份状态。 - 完善
rebind模板逻辑,保证容器生成适配不同类型的分配器时,状态能正确传递。
- 显式声明
通过指针共享状态规避多实例问题
VS的STL内部可能会多次复制分配器实例,你可以用智能指针(比如std::shared_ptr)管理分配器的状态数据,让多个分配器实例共享同一份状态,避免逻辑混乱。示例代码片段:template <typename T> class Mallocator { public: using value_type = T; using is_always_equal = std::false_type; struct State { // 自定义的分配器状态数据 int instance_id; }; std::shared_ptr<State> state; // 带状态的构造函数 Mallocator(int id) : state(std::make_shared<State>(id)) {} // rebind构造,共享状态 template <typename U> Mallocator(const Mallocator<U>& other) noexcept : state(other.state) {} // 内存分配函数 T* allocate(std::size_t n) { // 基于共享状态执行分配逻辑 return static_cast<T*>(std::malloc(n * sizeof(T))); } // 内存释放函数 void deallocate(T* p, std::size_t) noexcept { std::free(p); } // 相等性判断 friend bool operator==(const Mallocator& a, const Mallocator& b) noexcept { return a.state == b.state; } friend bool operator!=(const Mallocator& a, const Mallocator& b) noexcept { return !(a == b); } };启用VS特定的预处理器宏
在项目属性的预处理器定义中添加_ENABLE_STL_ALLOCATOR_HACK,这个宏会调整VS STL的分配器处理逻辑,减少不必要的分配器复制,提升对有状态分配器的支持度。显式传递分配器实例到容器
创建容器时,务必显式传入自定义分配器的实例,确保容器正确接收并保留状态:Mallocator<int> custom_alloc(100); std::list<int, Mallocator<int>> my_list(custom_alloc);
需要注意的是,VS的STL对有状态分配器的支持会随版本迭代优化,但上述方法可在当前17.8.5版本中有效规避问题。
内容的提问来源于stack exchange,提问作者QT-1
相关产品推荐
相关产品推荐

