Как следует из названия, у меня есть короткая демонстрационная программа, которая компилируется всеми этими компиляторами, но при запуске с помощью gcc 4.8 и gcc 4.9 сбрасывает дамп ядра:
Есть идеи, почему?
#include <unordered_map>
struct Foo : std::unordered_map<int,int> {
using std::unordered_map<int, int>::unordered_map;
// ~Foo() = default; // adding this allows it to work
};
struct Bar {
Bar(Foo f = {}) : _f(std::move(f)) {}
// using any of the following constructors fixes the problem:
// Bar(Foo f = Foo()) : _f(std::move(f)) {}
// Bar(Foo f = {}) : _f(f) {}
Foo _f;
};
int main() {
Bar b;
// the following code works as expected
// Foo f1 = {};
// Foo f2 = std::move(f1);
}
Мои настройки компиляции:
g++ --std=c++11 main.cpp
Вот трассировка из GDB:
#0 0x00007fff95d50866 in __pthread_kill ()
#1 0x00007fff90ba435c in pthread_kill ()
#2 0x00007fff8e7d1bba in abort ()
#3 0x00007fff9682e093 in free ()
#4 0x0000000100002108 in __gnu_cxx::new_allocator<std::__detail::_Hash_node_base*>::deallocate ()
#5 0x0000000100001e7d in std::allocator_traits<std::allocator<std::__detail::_Hash_node_base*> >::deallocate ()
#6 0x0000000100001adc in std::__detail::_Hashtable_alloc<std::allocator<std::__detail::_Hash_node<std::pair<int const, int>, false> > >::_M_deallocate_buckets ()
#7 0x000000010000182e in std::_Hashtable<int, std::pair<int const, int>, std::allocator<std::pair<int const, int> >, std::__detail::_Select1st, std::equal_to<int>, std::hash<int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_M_deallocate_buckets ()
#8 0x000000010000155a in std::_Hashtable<int, std::pair<int const, int>, std::allocator<std::pair<int const, int> >, std::__detail::_Select1st, std::equal_to<int>, std::hash<int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::~_Hashtable ()
#9 0x000000010000135c in std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, int> > >::~unordered_map ()
#10 0x00000001000013de in Foo::~Foo ()
#11 0x0000000100001482 in Bar::~Bar ()
#12 0x0000000100001294 in main ()
*** error for object 0x1003038a0: pointer being freed was not allocated
***
Bar(Foo f = {Foo()}) : _f(std::move(f)) {}
- person ThomasMcLeod   schedule 08.01.2014{}
иstd::unordered_map
конструкторов/деструкторов) - person zch   schedule 08.01.2014error: converting to 'Foo {aka std::unordered_map<int, int>}' from initializer list would use explicit constructor
- person vmrob   schedule 08.01.2014Foo
вызывается дважды - person user2485710   schedule 08.01.2014{}
вместо использования аргумента по умолчанию, и эти два параметра должны быть одинаковыми; но этот работает нормально, а второй вылетает. - person Adam Rosenfield   schedule 08.01.2014std::move
- person user2485710   schedule 08.01.2014~Foo() = default;
позволяет ему работать. - person vmrob   schedule 08.01.2014Bar(Foo f = {{1,2}})
, у меня работает, очевидно, когда initializer_list пуст, у вас возникают проблемы с выделением и освобождением. Я не знаю, настоящая это ошибка или нет, я хотел бы знать, что команда libstdc++ может сказать об этом. - person user2485710   schedule 08.01.2014f
и_f
bar не являются одним и тем же объектом. Когдаstd::move
завершится, вf
не останется кишок, которые можно уничтожить. Или я ошибаюсь? - person ThomasMcLeod   schedule 08.01.2014unordered_map
;std::move
— это приведение, это приведение запускает сигнатуруT&&
для конструктора, все дело в том, что происходит внутри конструктора. Я предполагаю, что в случае с пустым это не так хорошо обрабатывается, потому что, если вы предоставите хотя бы 1 пару, это сработает. В общем, вы ничего не можете сказать наверняка, когда у вас просто есть приведение типаstd::move
, конструктор здесь большой?
. - person user2485710   schedule 08.01.2014Foo f = {}
является виновником. Вот оно. Хотя, наверное, это не связано. Если да, то игнорируйте мой комментарий. - person   schedule 08.01.2014~Foo() = default;
решит проблему, это вполне может быть драйвер компилятора. - person vmrob   schedule 08.01.2014I'm not sure why I first thought it was with libstdc++, but after realizing that just adding that explicitly defined default destructor fixed it, I couldn't imagine it being the library.
Должен согласиться, я не думаю, что это связано с unordered_map. См. это и это. Хотя я могу ошибаться. - person   schedule 11.01.2014