сбой итератора c ++ при итерации по вектору

0

У меня есть класс Iformat, у которого есть оператор виртуальной функции(), и каждый производный класс реализует эту функцию.

class myClass
{
    std::vector<IFormat*> formatList_;
public:
  void formatAll()
  {
    foreach(IFormat* format , formatList_)
    {
        (*format)();
    }
  }

};

Функция formatAll вызывается объектом myClass а затем в цикле функция operator() myClass этот объект myClass, который вызывает formatAll() которая приводит к сбою, когда итераторы повреждаются.

Ограничения: определение operator() не может быть объявлено иначе, чтобы возвращать тип ошибки.
Кроме того, нельзя использовать некоторую индикаторную переменную для выхода из цикла.

Может кто-нибудь, пожалуйста, предложите способы обработки цикла, чтобы он не сбой, только изменяя цикл и итераторы и следуя ограничениям. благодаря

  • 0
    Я не думаю, что мы можем решить это без дополнительного контекста. Похоже, вы облажались с управлением памятью где-то вдоль линии, но вы могли облажаться где угодно. Если оператор () формата удаляет родительский элемент, то вы явно не определили владельца очень хорошо ...
  • 0
    Лучше всего продублировать проблему на небольшом примере. Извлеките достаточно из более крупной программы, чтобы сделать небольшой пример, который вы можете опубликовать, который демонстрирует проблему. Часто вы обнаружите проблему самостоятельно, работая над этим. если нет, то вы можете опубликовать пример, который другие могут скомпилировать и помочь вам отладить.
Показать ещё 1 комментарий
Теги:
boost
stl

1 ответ

0

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

У вас есть несколько вариантов:

  1. скопируйте formatList_ внутри formatAll и итерации по копии; вы только копируете указатели, но это может быть нежелательно, если контейнер большой, или если вы выполняете это в узком цикле где-то;

  2. в среде, управляемой событиями, вы можете отложить выполнение (*format)() до начала следующего приложения "tick", в этом цикле только добавив его в некоторую рабочую очередь; это фактически то же самое, что и вариант №1, намного сложнее, но если у вас есть такая структура, он может сложить действительно красиво;

  3. что каким-либо образом обратный вызов не может напрямую или косвенно изменить formatList_; вы можете достичь этого, запретив "добавить" или "удалить" параметры или заставить их отложить.

"Самый чистый" подход - это вариант № 3, но, опять же, если вы не находитесь в управляемой событиями инфраструктуре, это может быть неудобным для реализации.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню