带有自定义分配器的 std::string

Posted

技术标签:

【中文标题】带有自定义分配器的 std::string【英文标题】:std::string with a custom allocator 【发布时间】:2016-05-28 19:20:26 【问题描述】:

所以我目前正在编写内存调试器,为此我需要 stl 容器对象来使用未跟踪的分配器。

我在整个代码库中都添加了 std::string,因此我将其键入定义以使用我未跟踪的分配器:

typedef std::basic_string<char, std::char_traits<char>, UntrackedAllocator<char>> String;

现在当我尝试这样做时:

String str  "Some string" ;
String copy = str;

我收到此错误:

/usr/local/include/c++/7.1.0/ext/alloc_traits.h:95:67: error: no matching function for call to 'UntrackedAllocator<char>::UntrackedAllocator(UntrackedAllocator<char>)'  return _Base_type::select_on_container_copy_construction(__a); 

这就是我的未跟踪分配器的样子:

#pragma once

#define NOMINMAX
#undef max

template <typename T>
class UntrackedAllocator 
public:
    typedef T value_type;
    typedef value_type* pointer;
    typedef const value_type* const_pointer;
    typedef value_type& reference;
    typedef const value_type& const_reference;
    typedef std::size_t size_type;
    typedef std::ptrdiff_t difference_type;

public:
    template<typename U>
    struct rebind 
        typedef UntrackedAllocator<U> other;
    ;

public:
    inline explicit UntrackedAllocator() 
    inline ~UntrackedAllocator() 
    inline explicit UntrackedAllocator(UntrackedAllocator const&) 
    template<typename U>
    inline explicit UntrackedAllocator(UntrackedAllocator<U> const&) 

    //    address
    inline pointer address(reference r) 
        return &r;
    

    inline const_pointer address(const_reference r) 
        return &r;
    

    //    memory allocation
    inline pointer allocate(size_type cnt,
        typename std::allocator<void>::const_pointer = 0) 
        T *ptr = (T*)malloc(cnt * sizeof(T));
        return ptr;
    

    inline void deallocate(pointer p, size_type cnt) 
        free(p);
    

    //   size
    inline size_type max_size() const 
        return std::numeric_limits<size_type>::max() / sizeof(T);
    

    // construction/destruction
    inline void construct(pointer p, const T& t) 
        new(p) T(t);
    

    inline void destroy(pointer p) 
        p->~T();
    

    inline bool operator==(UntrackedAllocator const& a)  return this == &a; 
    inline bool operator!=(UntrackedAllocator const& a)  return !operator==(a); 
;

这是我第一次使用自定义分配器,所以我不知道它发生了什么。如果其中一个使用自定义分配器,我不能做 str1 = str2 ,这真是令人难以置信。

【问题讨论】:

您的关系运算符错误。分配器应该比较相等,只要一个可以释放另一个分配。 ***.com/help/mcve 错误信息暗示您在某处使用了复制构造函数。您发布的代码不使用构造函数的副本,但除非您的下标运算符按值返回。无论如何,使复制构造函数显式很少有用。从复制构造函数中删除explicit,一切都会好起来的。 @KerrekSB 你是什么意思? 【参考方案1】:

问题是复制 c'tors 声明为explicit

UntrackedAllocator 复制 c'tor 更改为:

inline UntrackedAllocator(UntrackedAllocator const&) 

解决了编译问题,一切正常:

int main() 
  String str  "13" ;
  String copy = str;
  const char* cstr = str.c_str();
  int out = atoi(cstr);

这是因为接受 const std::basic_string &amp;std::basic_string 的赋值运算符需要分配器的隐式复制构造。

【讨论】:

以上是关于带有自定义分配器的 std::string的主要内容,如果未能解决你的问题,请参考以下文章

为未初始化的std :: string变量分配了多少内存?

带有自定义删除器和分配器的 shared_ptr

传递给 std::basic_string 的分配器能否将其方法设为虚拟

带有自定义适配器的 Android ListView 有视觉故障

带有由 LoaderManager 管理的自定义适配器的 AlphabetIndexer

使用带有自定义对齐分配器实现的最新 g++ 使用 SSE 和 -O3 选项编译时出现非法指令(核心转储)