首页 > 解决方案 > std::map::find 和 std::map::end 很奇怪

问题描述

所以基本上几个小时前,我正在做我的项目,而我根本没有接触过的东西无缘无故地坏了。这段代码:

CFilesystem::working_directory_t &CFilesystem::GetThreadDirectories( )
{
    const auto dwThread = GetCurrentThreadId( );

    const auto pSearch = _ThreadDirectories.find( dwThread );
    volatile auto b = pSearch == _ThreadDirectories.end( );
    if ( pSearch == _ThreadDirectories.end( ) )
    {
        _ThreadDirectories.insert( std::pair< DWORD, working_directory_t >( dwThread, working_directory_t( ) ) );
        return GetThreadDirectories( );
    }

    return pSearch->second;
}

struct working_directory_t
{
    std::string strWorkingDirectory;
    std::stack< std::string > _DirectoryStack;

    working_directory_t( ) = default;
    void StoreCurrentWorkingDirectory( );
    void RestoreWorkingDirectory( );
};

std::map< DWORD, working_directory_t > _ThreadDirectories { };

不想再工作了。运行时,变量如下所示: Visual Studio 2019 屏幕截图 无论出于何种原因,变量 b 的计算结果为 false,即使 pSearch 明显等于 end,如图所示。如果我将黄色箭头拖到 if 语句中以执行插入到 _ThreadDirectories 中的代码,则会引发如下异常: 在此处输入图像描述

我已经尝试重建、重新启动 Visual Studio 2019 和我的 PC。我尝试过内联 CFileSystem 声明而不是外部化它以查看这是否会有所作为,但它没有。我不知道发生了什么,我会很感激任何帮助。提前致谢。

标签: c++

解决方案


首先,如果找不到线程 ID,该函数将调用自身。你不能只返回对插入值的引用吗?

其次,也是最重要的,如果多个线程访问同一个映射,它肯定需要一个互斥锁来使其线程安全。

我会实现这样的功能:

CFilesystem::working_directory_t &CFilesystem::GetThreadDirectories( )
{
    const auto dwThread = GetCurrentThreadId( );

    std::lock_guard<std::mutex> lock(mMutex);
    const auto pSearch = _ThreadDirectories.find( dwThread );

    if ( pSearch == _ThreadDirectories.end( ) )
    {
        _ThreadDirectories.insert( std::pair< DWORD, working_directory_t >( dwThread, working_directory_t( ) ) );
        return _ThreadDirectories[dwThread];
    }

    return pSearch->second;
}

其中 mMutex 是在 CFilesystem 中定义的 std::mutex 对象。

我还将保护使用 _ThreadDirectories 的其他函数中对地图的访问。你有删除条目的功能吗?如果是这样,也可以在那里使用 lock_guard。


推荐阅读