std :: map :: find和std :: map :: end很奇怪

时间:2019-06-29 06:22:25

标签: c++

因此,基本上在几个小时前,我正在做我的项目,而我完全没有碰到的东西由于没有明显的原因而破裂。这段代码:

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 screenshot 无论出于何种原因,即使pSearch明显等于end,变量b的计算结果仍为false,如图所示。如果将黄色箭头拖动到if语句中以执行插入_ThreadDirectories的代码,则会引发如下异常: enter image description here

我尝试重建,重新启动Visual Studio 2019和我的PC。我试过内联CFileSystem声明,而不是对其进行外扩,以查看这是否有所不同,但事实并非如此。我不知道发生了什么,不胜感激。预先感谢。

1 个答案:

答案 0 :(得分:1)

首先,如果找不到线程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。