使用 stl 矢量 at 而不是运算符 [] 时崩溃

发布于 2024-09-03 04:32:19 字数 2430 浏览 2 评论 0原文

我有一个方法如下(来自实现 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 使用 Intel C++ 11.0.074 [IA-32] 进行编译,并且我的矢量实现已关闭

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())
{
    ...

更新我已将编译器升级到最新版本 11.1.065,这种情况不再发生。看来哪里有什么奇怪的地方。

I have a method as follows (from a class than implements TBB task interface - not currently multithreading though)
My problem is that two ways of accessing a vector are causing quite different behaviour - one works and the other causes the entire program to bomb out quite spectacularly (this is a plugin and normally a crash will be caught by the host - but this one takes out the host program as well! As I said quite spectacular)

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

I hate not putting in well defined questions but at the moment my best phrasing is : "WTF?"

I'm compiling this with Intel C++ 11.0.074 [IA-32] using Microsoft (R) Visual Studio Version 9.0.21022.8 and my implementation of vector has

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

(Iterator debugging is off - I'm pretty sure) and

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

So the only difference I can see is that at calls begin instead of simply using _Myfirst - but how could that possibly be causing such a huge difference in behaviour?

UPDATE:

The index is within range - the size is printed out as 377 and the index is constrained to 129.

The member variable has an entry corresponding to accessMode

The entire thing has been wrapped in the following to clarify @nikko suggestion:

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

UPDATE I've upgraded my compiler to the latest version 11.1.065 and this is no longer happening. Looks like it was weirdness somewhere.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

拧巴小姐 2024-09-10 04:32:19

我没有看到您在哪里检查 rowTotalsForAccessMode 是否有效。也许你的“m_rowTotalsByAccessMode.find(accessMode)”不起作用。

您应该根据迭代器 end() 检查 .find() 的结果,看看它是否有效

I did not see where you checked that rowTotalsForAccessMode was valid. Maybe your "m_rowTotalsByAccessMode.find(accessMode)" does not work.

You should check the result of your .find() against iterator end() to see if it's valid

以歌曲疗慰 2024-09-10 04:32:19

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

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

Can't you single step the program in a debugger (into at) and see what is causing the crash? There are two options:

  1. rowTotalsForAccessMode is invalid
  2. origin is out of range
七度光 2024-09-10 04:32:19

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

我将在英特尔论坛上跟进此问题,感谢所有为解决此问题付出时间和精力的人。

I hate answering my own questions but this seems to be a situation where it is required. As it says in the update, I downloaded and installed the latest intel c++ compiler and recompiled from scratch which seems to have fixed the problem. I've also rebuilt the entire project from scratch using the 11.0.074 compiler to rule out a corruption of one of the binaries; even a clean build results in the crash!

I'm going to follow this up on the Intel forums, thanks to everyone who put in some time and effort to this problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文