删除导致基类中的虚拟析构函数导致内存错误

时间:2013-11-23 13:26:49

标签: c++ pointers delete-operator virtual-destructor

我真的不明白为什么我在这里得到错误的函数调用:

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

        }
    }
}

编辑:

好的,错误似乎在其他地方。当我发表评论时

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

不幸的是,类型是ALWAYS Event,但我需要的是对象的派生类型(在这种情况下是LogEvent,它是从Event派生的)。我是否需要将其设为模板函数,或者是否有办法获取对象的ACTUAL类型,无论它被投射到什么位置?

1 个答案:

答案 0 :(得分:0)

为了获得所需的type_index密钥,您必须将typeid()与引用或解除引用的指针一起使用,例如, msdncppreference很好地记录文件。

因此,将创建type_index的行更改为:

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

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

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

相关问题