3

So I'm currently in the process of writing a memory debugger and to do that I need stl container objects to use an untracked allocator.

I have std::string peppered throughout my entire codebase, so I typedef'd it to use my untracked allocator:

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

Now when I try to do this:

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

I get this error:

/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); } 

This is what my Untracked Allocator looks like:

#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); } }; 

This is my first time working with custom allocators so I have no idea what's going on with it. It's incredibly annoyning that I can't do str1 = str2 if one of them uses a custom allocator.

4
  • 2
    Your relational operators are wrong. Allocators should compare equal whenever one can deallocate the other's allocation. Commented May 28, 2016 at 19:26
  • stackoverflow.com/help/mcve Commented May 28, 2016 at 19:41
  • 2
    The error message implies that you are using a copy constructor somewhere. The code you posted doesn't use a copy a constructor, though unless your subscript operator returns by value. Anyway, making the copy constructor explicit is rarely useful. Remove the explicit from the copy constructor and things should be fine. Commented May 28, 2016 at 20:14
  • @KerrekSB What do you mean? Commented May 28, 2016 at 23:22

1 Answer 1

3

The problem is the declaration of the copy c'tors as explicit.

Changing the UntrackedAllocator copy c'tor to:

inline UntrackedAllocator(UntrackedAllocator const&) {} 

Solves the compilation issue and everything works just fine:

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

This happens because the assignment operator of the std::basic_string that accepts const std::basic_string & requires an implicit copy construction of the allocator.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.