【问题标题】:c++ Access violation reading location while erasing from list [closed]c ++从列表中擦除时访问冲突读取位置[关闭]
【发布时间】:2015-10-10 09:25:19
【问题描述】:

我有以下 c++ 代码:

typedef std::list< Volume >::iterator   pVolume;
typedef std::list< pVolume >::iterator  ppVolume;
void Node::delVolume( pVolume _volume )
{
    for( ppVolume it = m_volumes.begin( ); it != m_volumes.end( ); )
        if( (*it) == _volume )
        {
            it = m_volumes.erase( it );
            break;
        }
        else
            it++;
}

出现错误

Delone3D.exe 中 0x009a3c79 处未处理的异常:0xC0000005:访问 违规读取位置0xfeeefef2。

正好在擦除时。调试显示“it”和“_volume”都不是空指针。

这可能还有什么其他原因?

【问题讨论】:

  • Volumes 的析构函数是什么样子的?
  • Volume 的析构函数为空。 Volume 中的所有参数都是静态的。在这个函数中,我只删除指向 Volume 的指针,而不是对象本身。
  • 好吧,如果你没有在上下文中显示相关代码,我们什么也说不出来。
  • @OlzhasTurar 仅供参考:该循环可以替换为:auto iter = std::find(m_volumes.begin(), m_volumes.end(), _volume); if ( iter != m_volumes.end()) m_volumes.erase( iter );
  • @OlzhasTurar 您在应用程序的其他地方对指针管理不善。正是这段代码最终显示了损坏情况。

标签: c++ list exception erase


【解决方案1】:

您显示的代码是正确的,您的应用程序的其他地方似乎存在问题。内存模式0xfeeefef2(0xfeeefeee上方的几个地址)表示已释放动态内存,请参阅here。

顺便说一句,您可以大大简化您的代码:

// for std::list, as in your example
m_volumes.remove(_volume);

// for std::vector and std::deque
auto itr = std::remove(m_volumes.begin(), m_volumes.end(), _volume);
m_volumes.erase(itr, m_volumes.end());

【讨论】:

    【解决方案2】:

    我找到了产生错误的地方。但我不知道为什么。

    我的整个代码都是作为抽象事件类的继承者实现的

    class Event
    {
    public:
        Event( ) { }
        ~Event( ) { }
    
        virtual void Implement( void ) abstract;
        virtual void ReturnColors( void );      
    private:
    };
    

    有指向事件的指针的双端队列

    std::deque< Event * >   m_triangulationEvents;
    

    使用方式如下

    void Delaunay3D::nextEvent( )
            {
                if( !m_triangulationEvents.empty( ) )
                {
                    m_prevEvent->ReturnColors( );
    
                    Event * cur = m_triangulationEvents.front( );
                    m_triangulationEvents.pop_front( );
                    cur->Implement( );
    
                    delete m_prevEvent;
                    m_prevEvent = cur;
                }
            }
    

    问题出在

    delete m_prevEvent;
    

    字符串。评论它或使用

    m_prevEvent.~Event( );
    

    导致应用良好。谢谢大家。

    附: @TheOperator 感谢您提到释放的动态内存

    【讨论】:

    • -1 -- 你的修复不是修复。您不应该像那样显式调用析构函数。您的代码的一个明显问题是您的 Event 类缺少虚拟析构函数。
    • 是的,添加虚拟关键字后效果很好
    猜你喜欢
    • 2022-06-17
    • 2014-01-23
    • 1970-01-01
    • 2014-05-07
    • 1970-01-01
    • 2017-03-28
    • 2020-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多