断言试图删除一个空对象

时间:2011-09-08 22:19:47

标签: c++

尝试解决内存泄漏我改变了这个:

void addListener(IListener* listener, const std::string& appender )
{
     std::pair<t_ListenerVectorMap::iterator,bool> p =
    listenerVectorMap.insert(std::string(appender), new t_ListenerVector);
    p.first->second->push_back(listener);

    //add the appender
    addAppender(appender);
}

由此:

void addListener( IListener* listener,const std::string& appender )
{
    t_ListenerVector* lv = new t_ListenerVector;
    std::pair<t_ListenerVectorMap::iterator,bool> p =
    listenerVectorMap.insert(std::string(appender), lv);

    p.first->second->push_back(listener);
    if (!p.second)
    {
        delete lv;
    }

    addAppender(appender);
}

我正试图获得的泄漏是新的t_ListenerVector(是一个boost :: ptr_vector)。当appender已经存在于listenerVectorMap中时,插入操作不会修改map的内容,因此不会插入新的t_ListenerVector并成为mem泄漏。

改变是为了避免这种泄漏。如果没有新的插入,lv没有插入,所以我删除它。但问题是删除lv会抛出一个断言(在vc \ include \ vector Line:70中)。 如果lv没有改变,为什么会出现这个错误?

欢迎一些想法。 感谢

3 个答案:

答案 0 :(得分:2)

检查地图中是否存在首先,然后调用new来创建对象。这不一定是bug的来源,但它是一种更有效的练习。

答案 1 :(得分:1)

对于这个答案,我假设t_ListenerVectorMap的类型是boost::ptr_map<std::string, boost::ptr_vector<IListener>>。如果不是那么这个答案可能毫无价值。


您对boost::ptr_map的工作方式存在误解。确实,您的原始代码包含内存泄漏,但您的替换代码更糟糕。无论是否插入listenerVectorMap.insert(std::string(appender), lv)listenerVectorMap都会lv取得lv的所有权。这意味着delete lv;行会导致双重删除。

要修复代码的第一个版本中的内存泄漏,您所要做的就是:

void addListener(IListener* listener, const std::string& appender )
{
    std::auto_ptr<IListener> ls(listener);
    //The original code leaked here if the std::string constructor threw.
    std::pair<t_ListenerVectorMap::iterator,bool> p =
        listenerVectorMap.insert(appender, new t_ListenerVector());
    p.first->second->push_back(ls);

    //add the appender
    addAppender(appender);
}

答案 2 :(得分:0)

如果断言来自您的删除号码,我会检查以确保:

  1. lv已正确初始化。也许它有一个浮点指针,通过调用delete调用它的析构函数并让它尝试释放一段随机的内存?
  2. 如果插入失败,它不会为你清除你的记忆?
  3. 有关确切错误报告的更多具体信息会有所帮助。