0

У меня есть следующий код, который вычисляет число Стирлинга второго рода для данного п и к,Почему этот memoized код segfault?

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

К сожалению, когда этот код работает, он возвращает ошибку сегментации. Кажется, что он отлично работает для первых значений 87795, вставленных в memo, но затем сбой вскоре после этого. В частности, segfault происходит в map::count, в строке if (memo.count(nKPair) > 0) {. Я подумал, может быть это было делом memo иссякают размера, поэтому я добавил следующее предостережение в присвоении memo,

if (memo.size() < memo.max_size()) { 
    memo[nKPair] = val; 
} 

Но это не помогло. Я также заметил, что значение 87795 не указывает на то, когда это произойдет. С некоторыми незначительными изменениями, изменяя первый, если заявление,

if (n <= k) { 
    return 1; 
} 

изменяет это значение 66453.

Кто-нибудь знает, что здесь происходит?

+0

Где вы планируете вставить что-нибудь в памятку? –

+0

Вы уверены, что segfault находится на 'memo.count' линии и не делать с выдуванием стека через глубокую рекурсию из-за неправильной memoizing? – oldrinb

+0

@DavidThomas, не 'operator []' вставить новый элемент для ключа, если ключ еще не существует? –

ответ

0

Хорошо, поэтому после долгих раздумий я сузил это до вопроса шаблонов выражений. Я на самом деле не в полной мере понять, почему, но все это должно было сделать с этой маленькой auto в линии

auto val = k * stirlingS2(n - 1, k) + stirlingS2(n - 1, k - 1) 

В основном, изменения, которые auto к mp::cpp_int и вдруг, не Segfault.

Смежные вопросы