I have the following code that computes the Stirling number of the second kind for a given n and k,
#include <cstdint>
#include <map>
#include <boost/multiprecision/cpp_int.hpp>
namespace mp = boost::multiprecision;
mp::cpp_int stirlingS2(unsigned n, unsigned k)
{
if (n == 0 && k == 0) {
return 1;
}
if (n == 0 || k == 0) {
return 0;
}
static auto memo = std::map<std::pair<unsigned, unsigned>, mp::cpp_int>();
auto nKPair = std::pair<unsigned, unsigned>(n, k);
if (memo.count(nKPair) > 0) {
return memo[nKPair];
}
auto val = k * stirlingS2(n - 1, k) + stirlingS2(n - 1, k - 1);
memo[nKPair] = val;
return val;
}
Unfortunately, when this code is running, it segfaults. It seems to run fine for the first 87795 values inserted into memo
, but then crashes shortly thereafter. Specifically, the segfault happens at map::count
, in the line if (memo.count(nKPair) > 0) {
. I thought maybe this was a matter of memo
running out of size, so I added the following caveat to the assignment to memo
,
if (memo.size() < memo.max_size()) {
memo[nKPair] = val;
}
But that didn't help. I've also noticed that the 87795 value is not indicative of when this crashes. With some minor modifications, changing the first if statement to,
if (n <= k) {
return 1;
}
changes that value to 66453.
Does anyone know what's going on here?
Ok, so after hours of confusion, I narrowed this down to an expression templates issue. I don't really fully understand why, but it all had to do with that little auto
in the line
auto val = k * stirlingS2(n - 1, k) + stirlingS2(n - 1, k - 1)
Basically, change that auto
to mp::cpp_int
and suddenly, no segfault.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.