Я тестирую рекурсию, однако, когда у меня есть массив с более чем 150000 элементами, возникает ошибка сегментации. В чем проблема?
#include <iostream>
using namespace std;
void init ( float a[] , long int n );
float standard ( float a[] , long int n , long int i );
int main()
{
long int n = 1000000;
float *a = new float[n];
init ( a , n );
cout.precision ( 30 );
cout << "I got here." << endl;
cout << "Standard sum= " << standard ( a , 0 , n - 1 ) << endl;
delete [] a;
return 0;
}
void init ( float a[] , long int n )
{
for (long int i = 0 ; i < n ; i++ )
{
a[i] = 1. / ( i + 1. );
}
}
float standard ( float a[] , long int i , long int n )
{
if ( i <= n )
return a[i] + standard ( a , i + 1 , n );
return 0;
}
В качестве дополнения к правильному ответу MicroVirus, вот пример хвостовой рекурсивной версии вашего алгоритма:
float standard_recursion(float* a, long i, long n, long result) {
if(i > n)
return result;
return standard_recursion(a, i + 1, n, result + a[i]);
}
float standard(float* a, long i, long n ) {
return standard_recursion(a, i, n, 0);
}
Это должно выполняться, если компилятор оптимизирует оптимизацию вызовов (я тестировал на g++ -O2). Однако, поскольку функциональность зависит от оптимизации компилятора, я бы рекомендовал полностью исключить глубокую рекурсию и выбрать итеративное решение.
Скорее всего, вы исчерпали пространство стека в standard
рекурсивной функции, которое повторяется с глубиной n
, и оптимизация хвостового вызова, вероятно, здесь не включена.
Итак, чтобы ответить на вопрос в вашем названии: Да, существует предел рекурсии, и обычно это доступное пространство стека.
Возможно, вы потеряли память на куче. Кроме того, если вы получили 16 бит int, может возникнуть проблема с итерациями. Лучше использовать int32_t я вместо int i. То же самое с n.
int32_t
): придерживайтесь int или продолжайте долго, если только ширина типа не должна быть фиксирована до некоторого точного числа.