Я недавно узнал о пользовательских распределителях в C ++ 11 и пытаюсь использовать их в своем приложении.Однако я сталкиваюсь с segfault, который может быть воспроизведен следующим минимальным примером:
#include <vector>
#include <unordered_map>
#include <scoped_allocator>
template<class T> struct custom_allocator {
typedef T value_type;
custom_allocator() noexcept {}
template <class U> custom_allocator (const custom_allocator<U>&) noexcept {}
T* allocate (std::size_t n) { return static_cast<T*>(::operator new(n*sizeof(T))); }
void deallocate (T* p, std::size_t n) { ::delete(p); }
template <typename U> constexpr bool operator==(const custom_allocator<U>&) const { return true; }
template <typename U> constexpr bool operator!=(const custom_allocator<U>&) const { return false; }
};
template<class T> using custom_scoped_allocator = std::scoped_allocator_adaptor<custom_allocator<T> >;
typedef std::unordered_map<int, int, std::hash<int>, std::equal_to<int>,
custom_scoped_allocator<std::pair<const int, int> > > MyMap;
typedef std::vector<MyMap, custom_scoped_allocator<MyMap> > MyVector;
int main() {
MyVector vec(1);
vec[0][0] = 0;
return 0;
}
Пользовательский распределитель - тот, который предложен в примере в http://www.cplusplus.com/reference/memory/allocator_traits/. Затем он комбинируется сstd::scoped_allocator_adaptor
, как я видел в нескольких местах в Интернете.
Код прекрасно компилируется с gcc 5.4.0 с использованием g++ -g3 -O0 -std=c++11 -march=core-avx-i -o tmpalloc tmpalloc.cpp
.Когда я пытаюсь запустить его, появляется сообщение об ошибке, начиная с
*** Error in `./tmpalloc': double free or corruption (fasttop): 0x0000000000ae3c90 ***
. Если я перекомпилирую с помощью AddressSanitizer, я получу следующие сведения о двойном освобождении: https://pastebin.com/raw/xy2NQtD0 (извините за вставку, ноэто не красиво.) По сути, деструктор для объекта unordered_map, кажется, вызывается дважды.
Что я делаю не так?