Как правильно замтили отвечашие ранее, такие вещи надо искать в отладчике, а при чтении кода можно, разве что, заметить подозрительные места. В частности, я вижу подозрительное место в функции buildFanoTable - вот этот оператор:
if (abs(diff1 - diff2) < abs(diff1 - diff2 - frequencies[mid + 1].frequency)) {
mid++;
diff += frequencies[mid].frequency;
}
В предыдущем цикле mid может дойти до end-1, и обращение по индексу mid+1 будет как раз выходом за границу вектора.