unordered_map在Visual Studio中的神秘行为

Mysterious behavior of unordered_map in Visual Studio

本文关键字:Studio map Visual unordered      更新时间:2023-10-16

我想在VS2010 c++下在unsigned int索引处存储~3,000,000个double值。为此,我使用std::tr1:unordered_map<unsigned int, double>。不幸的是,当我尝试存储值2^21时,抛出了一个异常(好像只有2^21-1的空间,即某些索引只能使用20位)。在存储值之前,我尝试了rehash,这也不起作用。

最后,我完成了一些非常基本的测试程序(它甚至显示了一点不同的行为,但无论如何):

    std::tr1::unordered_map<unsigned int, float> mapOut;
    //mapOut.rehash(SOMESIZE);
    for (unsigned int i=0; i<3000000; i++)
    {
        if (i%1000==0) std::cout << i << std::endl;
        mapOut[i] = 0.0;
    }

有些情况我检查了:

1)如果我根本不重新哈希,程序在根据i == 32000(最终是2^15)输出后需要很长时间的休息,然后继续执行i == 262000(2^18)。在那里,它永远保持(100% CPU负载,内存不增加)。

2)如果我执行rehash(1000),它会到达i == 65000(2^16)并且永远保持(CPU负载100%,内存不增加)。

3)如果我执行rehash(3000000),循环成功结束,但程序永远不会退出——也就是说,显然析构函数有问题。

那里发生了什么,更重要的是:我该怎么办?!

非常感谢您的帮助!

连接上的以下错误似乎与您的问题有关:Visual c++: std::unordered_map析构器在调试配置中的性能

同样的问题不仅发生在析构函数中,而且在调整unordered_map的大小时也会发生。如果启用了迭代器调试,这似乎与使迭代器失效有关。

他们说VC11已经修复了。这里也列出了一些变通方法,但我还没有尝试过。

解决调试和发布版本的性能问题的一个非常简单的方法是在"配置选项/C/c++/预处理器/预处理器定义"下的项目选项中设置_SECURE_SCL=0_HAS_ITERATOR_DEBUGGING=0,这将完全禁用所有迭代器调试。但是,这也会禁用一些安全检查,因此您需要在自己的代码中更加小心。我相信这两个版本已经是默认的了,所以你不需要在那里做任何改变。

这似乎与示例代码的问题有关。我不确定最初的问题,因为你没有说抛出了什么异常。