同时 writing a post关于project euler's 14th problem我遇到了 VC9 和 VC10 之间的行为差异。
以下代码在 VC9 中运行正常,但在 VC10 中 std::unordered_map
抛出 bad_alloc
异常。
奇怪的是,如果我从异常中恢复过来, future 的分配将会成功(容器的大小继续增长)。另外,如果我使用 boost::unordered_map
,它在两个编译器中都能正常工作。
关于实际内存使用情况,我在一台有 4GB RAM 的机器上运行(正在使用 1.7),VC9 版本在完成任务之前获得了大约 810MB 的内存,而 VC10 版本在大约 658MB 时崩溃了。
这是 VC10 中的错误吗?我在同一台机器上运行,当完成的工作量相同时,还有什么可能导致内存在一个版本中持续用完,而在另一个版本中却没有?
更多信息: 第一次发生异常是在计算堆栈深度为 1 的 7,718,688 时(没有递归,只有 main->length)。之后,它似乎对添加到缓存中的每个数字都会发生。在异常发生之前缓存中有 16,777,217 个元素(根据 cache.size()
)。有趣的是,即使 insert
失败,缓存大小也会增加 1,因此它似乎不提供强异常保证(违反 §23.2.1.11)。
代码如下:
#include <iostream>
#include <unordered_map>
typedef std::unordered_map<_int64, int> cache_type;
_int64 collatz(_int64 i)
{
return (i&1)? i*3+1 : i/2;
}
int length(_int64 n, cache_type& cache)
{
if (n == 1)
return 1;
cache_type::iterator found = cache.find(n);
if (found != cache.end())
return found->second;
int len = length(collatz(n), cache) + 1;
cache.insert(std::make_pair(n, len)); // this sometimes throws
return len;
}
int main(int argc, char** argv)
{
const int limit = 10000000;
cache_type cache;
std::pair<int, int> max = std::make_pair(0, 0);
for (int i = 2; i <= limit; ++i) {
int len = length(i, cache);
if (len > max.second)
max = std::make_pair(i, len);
}
std::cout<< "Number with longest orbit is " << max.first
<< " with a lenght of " << max.second
<< " cache size is " << cache.size() << std::endl;
}
任何人都可以重现这种行为,一次它消失(并重新出现)所以我的配置可能有一些特别之处。
最佳答案
这可能是偶然的,但更改 _SECURE_SCL 的值会导致您描述的行为。
即编译:
cl /EHa /MD /D_SECURE_SCL=1 /Ox /c t1.cpp
link /LIBPATH:"c:/Program Files/Microsoft Visual Studio 10.0/VC/lib" /LIBPATH:"C:/Program Files/Microsoft SDKs/Windows/v7.0A/Lib" t1.obj
崩溃,但带有 _SECURE_SCL=0 的相同命令在我的 XP 32 位机器上运行完成。 msdn _SECURE_SCL 的页面表示它已启用调试构建,但未启用发布,如果您在 IDE 下构建,这可能很重要。
关于c++ - unordered_map 在 VS10 中抛出 bad_alloc 但在 VS9 中没有,这是一个错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3194730/