gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 18:27:01 26 4
gpt4 key购买 nike

我在运行一些传给我的旧代码时遇到了问题。它在 99% 的时间都有效,但偶尔,我注意到它会抛出“违反读取位置”异常。我有可变数量的线程可能在整个进程的生命周期内执行此代码。低出现频率可能表明存在竞争条件,但我不知道为什么在这种情况下会导致异常。这是有问题的代码:

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

在 map 的 operator[] 实现中抛出异常,在第一次调用 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。

感谢大家提出多线程问题的解决方案,但这不是这个问题要解决的问题。是的,我知道所提供的代码没有得到正确的保护,并且在它试图完成的事情上有点矫枉过正。我已经实现了修复。我只是想更好地理解为什么会抛出此异常。

最佳答案

给定地址“4”,“this”指针可能为空或迭代器有问题。您应该能够在调试器中看到这一点。如果为空,则问题不在该函数中,而在于调用该函数的人。如果迭代器不好,那就是你提到的竞争条件。大多数迭代器不能容忍列表被更新。

好的等等 - 这里没有 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,但其中一个成员是。

通过将 map 移出方法并以静态方式移入类中进行修复。然后它将在启动时初始化。否则,您必须在 doStuff() 调用周围放置一个 CR。您可以通过在 map 本身的使用周围放置一个 CR(例如,在 DoStuff 使用 operator[] 的地方)来防止剩余的 MT 问题。

关于c++ - std::map operator[] 中的违规读取位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/231885/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com