2013-11-23 45 views
0

我真的不明白,爲什麼我弄爛函數調用的位置:刪除導致內存錯誤

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

eEvent派生的對象的實例。 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; 
      } 

     } 
    } 
} 

編輯:

好吧,錯誤似乎是在別處。當我評論出

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(),例如, msdncppreference很好的文檔。

所以更改線路創建type_index到:

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

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

我相信第一個版本更清晰。