Периодически очищайте карту - PullRequest
1 голос
/ 06 марта 2019

У меня есть класс A, управляющий картой.

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;
};

Поскольку я добавляю много элементов в свою карту, я хочу периодически очищать ее, удаляя элементы, которые были впервые вставлены.

if (difftime(time(nullptr), _deque.front().second > EXPIRY)) {
  cleanMap();
}

В какой-то момент происходит сбой следующего кода при попытке извлечь элемент из deque:

double free or corruption (fasttop): 0x00007fffdc000900 ***

Имеет ли смысл приведенный выше код?Если да, где может быть ошибка?А если нет, то как я могу периодически чистить карту?

1 Ответ

3 голосов
/ 06 марта 2019

У вас проблемы при добавлении элементов с одинаковым ключом.

Когда вызывается emplace_hint с существующим ключом, вы нажимаете дублирующиеся итераторами deque (emplace_hint возвращает итератор в уже существующий элемент map :: emplace_hint ). Когда очищены deque и map, вы вызываете map::erase, но он принимает только действительные и разыменовываемые итераторы. Поэтому, когда для дублированного итератора вызывается erase ( map :: erase ), код падает, поскольку этот элемент был удален при предыдущем вызове erase.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...