I have a A class managing a map.
class A {
public:
A() {}
void addElem(uint8_t a, const B& b) {
std::lock_guard<std::mutex> lock(_mutex);
auto result = _map.emplace_hint(_map.end(), a, b);
_deque.push_back(std::make_pair(result, time(nullptr)));
}
void cleanMap() {
std::lock_guard<std::mutex> lock(_mutex);
_map.erase(_deque.front().first);
_deque.pop_front();
}
private:
std::map<uint8_t, B> _map;
std::deque<std::pair<std::map<uint8_t, B>::iterator, time_t>> _deque;
std::mutex _mutex;
};
As I add a lot of elements in my map, I want to periodically clean it by removing elements that were first inserted.
if (difftime(time(nullptr), _deque.front().second > EXPIRY)) {
cleanMap();
}
The following code is crashing at some point when I try to pop element from deque:
double free or corruption (fasttop): 0x00007fffdc000900 ***
Is the above code makes sense ? If yes, where could be the error ? And if not, how can I clean periodically a map ?
You have problems when you add the elements with the same key.
When emplace_hint
is called with the key which exists, you push on deque duplicated iterators (emplace_hint
returns the iterator to already existing element map::emplace_hint).
When deque and map are cleared, you call map::erase
but it accepts only valid and dereferenceable iterators. So when erase
is called for the duplicated iterator (map::erase), the code crashes because this item was deleted in previous erase
call.