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.
在实际记忆使用方面,Im在4GB RAM(1.7在使用中)的机器上运行,VC9版本在完成任务之前可达到810德国马克,VC10在~658MB坠毁。
这在VC10中是否是一种ug? 我坐在同一机器上,如果做的工作数量相同,那么怎么能以一个版本而不是另一个版本来持续记忆?
<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>
法典如下:
#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>