使用stl向量代替operator []时崩溃

时间:2010-05-26 09:36:58

标签: c++ stl vector crash

我有一个方法如下(从一个类而不是实现TBB任务接口 - 虽然目前不是多线程) 我的问题是,两种访问向量的方式导致了完全不同的行为 - 一种是有效的,另一种是导致整个程序轰炸得非常惊人(这是一个插件,通常崩溃将被主机捕获 - 但这一个需要主持人计划也是如此!正如我所说的非常壮观)

void PtBranchAndBoundIterationOriginRunner::runOrigin(int origin, int time) const // NOTE: const method
{
    BOOST_FOREACH(int accessMode, m_props->GetAccessModes())
    {
        // get a const reference to appropriate vector from member variable
        // map<int, vector<double>> m_rowTotalsByAccessMode;
        const vector<double>& rowTotalsForAccessMode = m_rowTotalsByAccessMode.find(accessMode)->second;

        if (origin != 129) continue; // Additional debug constrain: I know that the vector only has one non-zero element at index 129

        m_job->Write("size: " + ToString(rowTotalsForAccessMode.size()));
        try {
            // check for early return... i.e. nothing to do for this origin 
            if (!rowTotalsForAccessMode[origin])    continue; // <- this works
            if (!rowTotalsForAccessMode.at(origin)) continue; // <- this crashes
        } catch (...) {
            m_job->Write("Caught an exception"); // but its not an exception
        }

        // do some other stuff
    }
}

我讨厌不提出定义明确的问题,但目前我的最佳措辞是:“WTF?”

我正在使用Microsoft(R)Visual Studio版本9.0.21022.8使用英特尔C ++ 11.0.074 [IA-32]进行编译,而我的vector实现已经

const_reference operator[](size_type _Pos) const
{   // subscript nonmutable sequence

#if _HAS_ITERATOR_DEBUGGING
    if (size() <= _Pos)
    {
        _DEBUG_ERROR("vector subscript out of range");
        _SCL_SECURE_OUT_OF_RANGE;
    }
#endif /* _HAS_ITERATOR_DEBUGGING */
    _SCL_SECURE_VALIDATE_RANGE(_Pos < size());

    return (*(_Myfirst + _Pos));
}

(迭代器调试已关闭 - 我很确定)和

const_reference at(size_type _Pos) const
{   // subscript nonmutable sequence with checking
    if (size() <= _Pos)
        _Xran();
    return (*(begin() + _Pos));
}

所以我能看到的唯一区别是,在调用开始时而不是简单地使用_Myfirst - 但这怎么可能导致行为如此巨大的差异呢?

更新

索引在范围内 - 大小打印为377,索引限制为129.

成员变量有一个对应于accessMode

的条目

以下内容包含以下内容,以澄清@nikko建议:

map<int, vector<double>>::const_iterator it = m_rowTotalsByAccessMode.find(accessMode);
if (it != m_rowTotalsByAccessMode.end())
{
    ...

UPDATE 我已将我的编译器升级到最新版本11.1.065,现在不再发生这种情况了。在某个地方看起来很古怪。

3 个答案:

答案 0 :(得分:3)

我没看到你检查rowTotalsForAccessMode有效的位置。也许你的“m_rowTotalsByAccessMode.find(accessMode)”不起作用。

你应该检查你的.find()对iterator end()的结果,看看它是否有效

答案 1 :(得分:0)

你不能在调试器中单步执行程序(进入at)并查看导致崩溃的原因吗?有两种选择:

  1. rowTotalsForAccessMode无效
  2. origin超出范围

答案 2 :(得分:0)

我讨厌回答我自己的问题,但这似乎是需要它的情况。正如它在更新中所说,我下载并安装了最新的intel c ++编译器,并从头开始重新编译,似乎解决了这个问题。我还使用11.0.074编译器从头开始重建整个项目,以排除其中一个二进制文件的损坏;即使是干净的构建也会导致崩溃!

我将在英特尔论坛上关注此事,感谢所有为此问题付出一些时间和精力的人。