Search code examples
c++stdmapstddeque

Clean map periodically


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 ?


Solution

  • 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.