同时 写一个职位 关于 项目euler第14问题 我遇到了一个差别在行为之间的VC9和VC10.

以下代码运行中的"确定"VC9但在VC10 std::unordered_map 抛出了一个 bad_alloc 例外。奇怪的是,如果我从中恢复的例外的未来分配会成功(该容器的尺寸继续增长).此外,如果我使用 boost::unordered_map 它的工作现在两个编译器。

关于实际存使用情况、我上运行的计算机4G RAM(1.7在使用)的VC9版本得到高达~810MB的存储器之前完成任务和VC10一个崩溃的-658MB.

这是一个错误,在VC10?我在同一台机器上运行的还有什么可能导致存始终如一地运行了一个版本,而不是在其他当量工作是相同的?

<edit>
一些更多的信息: 第一时间的异常发生的是当计算7,718,688一堆深1(没有递归只是主>的长度)。之后,它似乎发生的每个数字,加入到缓存。缓了16,777,217元素在它之前的异常发生的(根据 cache.size()).有趣的是,甚至时 insert 失败的高速缓存大小的增长由之一,所以它的出现,它没有提供强大的例外的保证(违反第23.2.1.11).
</edit>

代码如下:

#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>
还有谁可以再现这种行为,在一段时间消失(和重新出现了)因此可能有一些特别的东西对我的结构。
</edit>

有帮助吗?

解决方案

这可能是附带的,而改变价值的_SECURE_SCL导致行你描述。

i。e编制有:

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运行,以完成我XP32位机。的 msdn 页_SECURE_SCL说,它的启用,为调试版本,但不释放,这可能是重要的,如果你在楼下IDE。

其他提示

插入一个单元可能会导致一个大型存储器的分配如果地图的散列表需要调整。地图似乎是有关0.5GB结束时运行。(见我的评论上。)

还有大概一些启发式被用来决定如何展开的散列表时,它需要增长,而这有可能是双它每次.这因此将使用~1.5GB老+新的数据同时散列表是被复制。

因此,可能你的计划是打限制过程中存的大小。(见的评论。) 如果是这样,这有可能是VC10需要稍微更多的存储器的整体比VC9,稍微不同数量的存储器中获得的分配在不同的运行,或建立程序,以便VC10命的限制有时在VC9没打过它。

不_int64有准的要求,地图可能不是表彰在分配?

尝试使用长长int代替,看看如果该行为的改变。

1-检查事件日志,看看是否有任何事件在谈论一个过程要超过允许限额。

2-如果你是32位的操作系统开始尝试与3GB用户的空间。

3-看看如果你有不同的分配可用

4-Diff序映射中在9.0和10.0及它的内文件对在非的机会,有一个人造的大小限制加入("安全特征":-).它将最可能在一个宏观与不同的价值观x86和64建立。

5-试着放轻的包装的分配程序并就印尺寸对于每个分配。这还会告诉你如果这是真的分配程序,投掷或者东西之前。

6-如果它是分配器投掷看看实际WinNT API调由它(和差异与9.0再次)

7-试图预先分配的巨大块(说1GB)。

你们吹的堆在深递归的呼叫 length().

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top