1.Это неопределенное поведение? Да.Вы никогда не должны копировать объекты, используя realloc (), потому что иногда они имеют внутренние указатели, которые указывают на ресурс.Проблема возникает позже, когда на двух разных объектах работают деструкторы.Теперь происходит двойное освобождение одного и того же ресурса , полный номер нет.
2.Можете ли вы предложить исправление или обходной путь, который можно применить к коду приложения (не изменяя Sparsehash или избегая его использования)?
Попробуйте
#include <memory>
и измените строку
google::dense_hash_map<std::string, int> map;
до
google::dense_hash_map<std::string, int, std::hash<std::string>, std::equal_to<std::string>, std::allocator> map;
Теперь он не будет использовать распределитель Google libc_allocator_with_realloc
3.(Бонусные баллы) Можете ли вы создать программу, которая на самом деле ведет себя неправильно из-за этого (используя std :: string или ваш собственный нетривиальный тип)?До сих пор я не видел никаких проблем в коде с использованием std :: string в качестве типа ключа, несмотря на тот факт, что std :: string должен быть довольно распространенным типом ключа.
Не так просто.Потому что вы пытаетесь вызвать неопределенное поведение.В вашей тестовой программе я бы передавал строки длиной не менее 32 символов, поэтому оптимизация небольших строк не запускается. И в куче gcc можно выполнить тесты, чтобы проверить, не испортилась ли она.См 1