当前位置:  开发笔记 > 编程语言 > 正文

std :: map operator []中的违规读取位置

如何解决《std::mapoperator[]中的违规读取位置》经验,为你挑选了1个好方法。

我在运行传给我的一些旧代码时遇到了一个问题.它可以在99%的时间内工作,但偶尔会发现它会抛出"违规读取位置"异常.我有可变数量的线程可能在整个过程的生命周期中执行此代码.低出现频率可能表示竞争条件,但我不知道为什么在这种情况下会导致异常.这是有问题的代码:

MyClass::Dostuff()
{
    static map mappedChars;
    if (mappedChars.empty())
    {
       for (char c = '0'; c <= '9'; ++c)
       {
          mappedChars[c] = c - '0';
       }
    }
    // More code here, but mappedChars in not changed.
}

在第一次调用operator []时,在map的operator []实现中抛出异常(使用STL的VS2005实现.)

mapped_type& operator[](const key_type& _Keyval)
{
    iterator _Where = this->lower_bound(_Keyval); //exception thrown on the first line
    // More code here
}

我已经尝试在operator []中冻结线程并尝试让它们同时运行它,但是我无法使用该方法重现异常.

你能想出为什么会抛出这种情况,而且只有部分时间?

(是的,我知道STL不是线程安全的,我需要在这里进行更改.我很好奇为什么我看到上面描述的行为.)

根据要求,这里有一些关于异常的更多细节:
app15-51-02-0944_2008-10-23.mdmp中0x00639a1c(app.exe)的未处理异常:0xC0000005:访问冲突读取位置0x00000004.

感谢大家提出多线程问题的解决方案,但这不是这个问题要解决的问题.是的,我理解所呈现的代码没有得到正确的保护,并且在它试图完成的内容方面有些过分.我已经有了实现它的修复程序.我只是想更好地理解为什么要抛出这个异常.



1> Tony Lee..:

给定地址"4",可能"this"指针为null或迭代器不好.您应该能够在调试器中看到这一点.如果这是null,那么问题不在于该函数,而是谁正在调用该函数.如果迭代器是坏的,那么这就是你所提到的竞争条件.大多数迭代器都不能容忍正在更新的列表.

好的等等 - 这里没有FM.静态首次使用时初始化.执行此操作的代码不是多线程安全的.一个线程正在进行初始化,而第二个线程认为它已经完成但它仍在进行中.结果是使用未初始化的变量.你可以在下面的程序集中看到这个:

static x y;
004113ED  mov         eax,dword ptr [$S1 (418164h)] 
004113F2  and         eax,1 
004113F5  jne         wmain+6Ch (41141Ch) 
004113F7  mov         eax,dword ptr [$S1 (418164h)] 
004113FC  or          eax,1 
004113FF  mov         dword ptr [$S1 (418164h)],eax 
00411404  mov         dword ptr [ebp-4],0 
0041140B  mov         ecx,offset y (418160h) 
00411410  call        x::x (4111A4h) 
00411415  mov         dword ptr [ebp-4],0FFFFFFFFh

初始化时,$ S1设置为1.如果设置,(004113F5)它跳过初始化代码 - 冻结fnc中的线程将无济于事,因为此检查是在进入函数时完成的.这不是null,但其中一个成员是.

通过将地图移出方法并将其作为静态移动到类中进行修复.然后它将在启动时初始化.否则,你必须在调用DoStuff()周围放置一个CR.您可以通过围绕地图本身的使用放置CR来保护其余的MT问题(例如,DoStuff使用operator []).

推荐阅读
郑谊099_448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有