unordered_map在VS10中抛出bad_alloc,但不是在VS9中,这是一个错误? [英] unordered_map throws bad_alloc in VS10 but not in VS9, is this a bug?

查看:218
本文介绍了unordered_map在VS10中抛出bad_alloc,但不是在VS9中,这是一个错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

撰写帖子时关于项目euler的第14个问题我碰到VC9和VC10之间的行为差​​异。 / p>

以下代码在VC9中运行,但在VC10中运行 std :: unordered_map throws a bad_alloc 异常。
奇怪的是,如果我从异常恢复,未来的分配将成功(容器的大小继续增长)。如果我使用 boost :: unordered_map 它在两个编译器工作正常。



关于实际内存使用,我在运行在一台有4GB RAM的机器上(使用1.7),VC9版本在完成任务之前可以达到〜810MB的内存,而VC10会在〜658MB的时候崩溃。



这是VC10中的错误吗?我在同一台机器上运行什么可能会导致内存在一个版本中一直用完,而完成的工作量是相同的,而不是在其他?



< sub>< edit>

一些更多信息:第一次发生异常时,计算7,718,688,堆栈深度为1 - >长度)。之后,它似乎发生在每个数字被添加到缓存。在异常发生之前,缓存有16,777,217个元素(根据 cache.size())。有趣的是,即使 insert 失败,缓存大小也会增加1,因此它似乎不能提供强异常保证(违反§23.2.1.11) 。

< / edit>



代码如下:

  #include< iostream> 
#include< unordered_map>

typedef std :: unordered_map< _int64,int> cache_type;

_int64 collat​​z(_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(collat​​z(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<< 具有最长轨道的数字是< max.first
<< ,具有<< max.second
<< cache size is< cache.size()< std :: endl;
}

< edit>

任何人都可以重现这种行为,一次消失(并重新出现),所以可能有一些特殊的我的配置。

< / edit> / p>

解决方案

这可能是偶然的,但是更改_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 / Libt1.obj

崩溃,但是与_SECURE_SCL = 0相同的命令在我的XP 32位机器上运行完成。 _SECURE_SCL的 msdn 页面表示已启用调试版本,但不能发布,如果您在IDE下构建,这可能很重要。


While writing a post about project euler's 14th problem I ran into a difference in behaviour between VC9 and VC10.

The following code runs OK in VC9 but in VC10 std::unordered_map throws a bad_alloc exception. The strange thing is that if I recover from the exception future allocations will succeed (the size of the container continues to grow). Also if I use boost::unordered_map it works fine in both compilers.

Regarding the actual memory usage, I'm running on a machine with 4GB RAM, (1.7 in use) the VC9 version gets up to ~810MB of memory before completing the task and the VC10 one crashes at ~658MB.

Is this a bug in VC10? I'm running on the same machine what else could cause memory to consistently run out in one version and not in the other when the amount of work done is identical?

<edit>
Some more information: The first time the exception takes place is when calculating 7,718,688 with a stack depth of 1 (no recursion just main->length). After that it seems to happen for each number that is added to the cache. The cache had 16,777,217 elements in it before the exception happened (according to cache.size()). The interesting thing is that even when insert fails the cache size grows by one so it appears that it doesn't supply the strong exception guarantee (in violation of §23.2.1.11).
</edit>

Code follows:

#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;
}

<edit>
Also can anyone reproduce this behaviour, at one time it disappeared (and re-appeared) so there may be something special about my configuration.
</edit>

解决方案

It might be incidental, but changing the value of _SECURE_SCL causes the behavoir you describe.

i.e Compiling with:

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

crashes, but the same commands with _SECURE_SCL=0 runs to completion on my XP 32bit machine. The msdn page for _SECURE_SCL says it's enabled for debug builds, but not release, which might be important if you're building under the IDE.

这篇关于unordered_map在VS10中抛出bad_alloc,但不是在VS9中,这是一个错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆