【问题标题】:0xC0000005: Access violation reading location 0x00000004 with QStack<std::map<std::string,std::string > > appending0xC0000005:访问冲突读取位置 0x00000004 与 QStack<std::map<std::string,std::string >> 附加
【发布时间】:2012-11-18 14:55:13
【问题描述】:

我有 QStack > 一直被填满 从我用 QMutexLocker 保护它的应用程序中,它从不同的线程中填充 QStack 是静态的。 现在经过几次插入,我得到了:

0xC0000005: Access violation reading location 0x00000004  

这是出现异常的函数

bool MyClass::AppendToLinks(QVector<std::map<std::string,std::string > >& linksvec)
{
    try
    {

        static QMutex mutex;
        QMutexLocker locker(&mutex);

        //used to: be m_OuterLinksToProcessOutStack+= linksvec;

        QStack<std::map<std::string,std::string > > stackTemp;
        stackTemp = m_OuterLinksToProcessOutStack;
        stackTemp  << linksvec;
            // here is where the exception appear :
        m_OuterLinksToProcessOutStack = stackTemp;
        locker.unlock();
        if(m_OuterLinksToProcessOutStack.size()>0)
        {

            return true;
        }

        return false;
    }
    catch (std::exception const & e)
    {
        std::cout << "Standard exception: " << e.what() << std::endl;

    }
    catch (...)
    {
        std::cout << "Unknown exception." << std::endl;

    }
}

这是堆栈:

myapp.exe!std::_Tree<std::_Tmap_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >,0> >::_Copy(const std::_Tree<std::_Tmap_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >,0> > & _Right={...})  Line 1063 + 0x11 bytes    C++
    myapp.exe!std::_Tree<std::_Tmap_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >,0> >::_Tree<std::_Tmap_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >,0> >(const std::_Tree<std::_Tmap_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >,0> > & _Right={...})  Line 536  C++
    myapp.exe!QVector<std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > > >::realloc(int asize=12, int aalloc=12)  Line 532 + 0x1e bytes    C++
    myapp.exe!QVector<std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > > >::operator+=(const QVector<std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > > > & l={...})  Line 684    C++
    myapp.exe!MyClass::AppendToLinks(QVector<std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > > > & linksvec={...})  Line 93   C++

QVector 和 Stacks 看起来都不是空的或 null 还能是什么?

【问题讨论】:

  • 我的经验是这种错误(从可疑接近 0 的地址读取)几乎总是由传递空指针或空引用引起。 (是的,你可以创建一个空引用,有时非常容易。当然是 UB,但这并不意味着它们不会发生。它只是意味着行为是未定义的。)

标签: c++ visual-studio exception qt4


【解决方案1】:

如果mutex 正在保护对m_OuterLinksToProcessOutStack 的访问,您应该在对if(m_OuterLinksToProcessOutStack.size()&gt;0) 的调用中保持锁定。所以在 try 块内你想要这样的东西:

static QMutex mutex;
QMutexLocker locker(&mutex);
m_OuterLinksToProcessOutStack += linksvec;
return !m_OuterLinksToProcessOutStack.isEmpty();

不过,这看起来还是有点可疑。如果这是在您的程序中访问m_OuterLinksToProcessOutStack唯一 位置,那么您可以将互斥锁作为本地静态对象。但如果它在其他任何地方被访问,mutex 将无法保护m_OuterLinksToProcessOutStack

如果m_OuterLinksToProcessOutStack 在其他地方被访问,您需要在这些地方也有相同的互斥锁可用(例如,使其成为类成员)。

【讨论】:

  • 我只想补充一点,QMutexLocker 不需要您在返回之前解锁它。使用 QMutexLocker 的美妙之处在于它会在其析构函数中自动解锁其 QMutex,让您无需记住在每个退出点手动解锁它。
【解决方案2】:

在我看来,m_OuterLinksToProcessOutStack 正在另一个函数中被访问(通过从 QStack 中提取链接的阅读器?)并且该位置不受互斥锁的保护。因此,当您尝试重新定义 m_OuterLinksToProcessOutStack 而另一个线程正在使用它时,您会收到错误。

当你重新定义你的容器时,它必须首先销毁它之前的内容,然后再接受新的内容。如果当前正在使用容器,您可以看到为什么这可能是一个问题。为什么要创建一个临时堆栈而不是直接附加到m_OuterLinksToProcessOutStack

另外,您在该函数中混合了 QVector 和 QStack。应该不是问题,但这可能取决于您以后如何访问它。

【讨论】:

    猜你喜欢
    • 2014-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多