2013-11-23 5 views
0

Я не понимаю, почему я получаю плохой вызов функции здесь:Ошибка при удалении причины памяти с виртуальным деструктора в базовом классе

Event* e = *(it->second.begin()); 
callbackBindings[it->first](e); 
delete e; 

e является экземпляром объекта, полученного из Event. Event имеет общедоступный виртуальный деструктор. Мой производный класс имеет пустой, но реализованный деструктор. delete e дает мне ошибку памяти здесь. Зачем? (e является допустимым указателем)

редактировать: полный код, может быть, это помогает:

#include "EventHandler.h" 
std::unordered_map<std::type_index, std::function<void(Event*)>> EventHandler::callbackBindings = std::unordered_map<std::type_index, std::function<void(Event*)>>(); 
std::unordered_map<std::type_index, std::list<Event*>> EventHandler::eventList = std::unordered_map<std::type_index, std::list<Event*>>(); 
void EventHandler::Update() 
{ 
    auto it = eventList.begin(); 
    while(it != eventList.end()) 
    { 
     if(it->second.size() < 1) //erase empty event lists! 
     { 
      eventList.erase(it++); 
     } 
     else 
     { 

      if(callbackBindings.count(it->first) < 0) //erase events without listener! 
      { 
       //delete all messages 
       auto eventIt = it->second.begin(); 
       while(eventIt != it->second.end()) 
       { 
        Event* e = *(eventIt++); 
        delete e; 
       } 
       //remove list entry 
       eventList.erase(it++); 
      } 
      else //perform callback 
      { 
       auto eventIt = it->second.begin(); 
       while(eventIt != it->second.end()) 
       { 
        //dereference iterator for ease of use & iterate 
        Event* e = *(eventIt++); 
        //callback function 
        callbackBindings[it->first](e); 
        //remove event from list 
        it->second.remove(e); //with a single message, this is where it crashes! 
        //delete event 
        delete e; 
       } 
       ++it; 
      } 

     } 
    } 
} 

EDIT:

Хорошо, ошибка, кажется, где-то в другом месте. Когда я прокомментирую

callbackBindings[it->first](e); 

Это не сбой?!

Редактировать: О, моя ошибка находится в другом месте!

Следующая функция должна поместить объект в карту, индексированные по его типу:

static void DispatchEvent(Event* e) 
    { 
     //te.event = e; 
     auto index = std::type_index(typeid(&e)); 
     //eventList.push_back(te); 
     if(eventList.count(index) < 1) 
     { 
      eventList[index] = std::list<Event*>(); 
     } 
     eventList[index].push_back(e); 
    } 

к сожалению, тип всегда событие, но то, что мне нужно, это производный тип объекта (LogEvent в этот случай, который получен из события). Мне нужно сделать это функцией шаблона или есть способ получить тип объекта ACTUAL, независимо от того, к чему он был добавлен?

+1

Возможно, повреждение памяти в коде, который вы еще не указали. Можете ли вы предоставить [SSCCE] (http://sscce.org/)? – Angew

+0

«Событие имеет открытый виртуальный деструктор». - Надеюсь, это не чистый виртуальный деструктор? –

+0

Я не думаю, что это чисто: public: virtual ~ Event() {}; – pixartist

ответ

0

Для того, чтобы получить желаемый ключ type_index, вы должны использовать typeid() с указателем ссылки или разыменованием, например. msdn или cppreference красивый документ.

Так измените строку создавая type_index для:

std::type_index index = typeid(*e); 

или

auto index = std::type_index(typeid(*e)); 

Я считаю, что первый вариант будет более четким.