C++ 递归有限制吗?

C++ 递归有限制吗?,c++,C++,我正在测试递归,但是当我有一个超过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

我正在测试递归,但是当我有一个超过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;
}
#包括
使用名称空间std;
void init(float a[],long int n);
浮动标准(浮动a[],长整数n,长整数i);
int main()
{
长整数n=1000000;
浮动*a=新浮动[n];
init(a,n);
计算精度(30);

cout可能堆上的内存不足。此外,如果得到16位int,则迭代可能有问题。最好使用int32_t i而不是int i。与n相同。

可能堆上的内存不足。如果得到16位int,则迭代可能有问题。最好使用int32_t i而不是int i。与n相同。

递归函数
standard
(其递归深度为
n
)中的堆栈空间很可能用完,此处可能未启用尾部调用优化


因此,为了回答标题中的问题:是的,递归有一个限制,通常是可用的堆栈空间。

您的递归函数
标准
中的堆栈空间很可能已经用完,该函数递归深度为
n
,这里可能没有启用尾部调用优化


因此,为了回答标题中的问题:是的,递归有一个限制,通常是可用的堆栈空间。

作为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上测试过),则应该运行该命令。但是,由于功能取决于编译器优化,我建议完全避免深度递归,并选择迭代解决方案。

作为对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上进行了测试),则应该运行此功能。但是,由于功能取决于编译器优化,我建议完全避免深度递归,并选择迭代解决方案。

是的,它是,这是我传递到那里的指针。我误读了,对不起,我认为你的意思是“递归”而不是“回溯”。在任何情况下,trhat闻起来更多的是堆栈溢出而不是分段错误。我得到了以下结果:
我到了这里。分段错误(内核转储)
是的,它是一个指针,我传递到那里。我读错了,对不起,我认为你的意思是“递归”而不是“回溯”。在任何情况下,trhat闻起来更多的是堆栈溢出,而不是分段错误。我得到了以下结果:
我在这里得到了。分段错误(内核转储)
我怀疑他正在耗尽堆空间。150000个浮点大约是半兆字节。没有理由在这里使用显式位大小类型(即
int32\u t
):请坚持使用int,否则会持续很长时间,除非类型的宽度需要固定到某个精确的数字。@user2079303:它不会是150000个浮点数。它将是150000个堆栈帧-所有局部变量的总和+返回点OK。我现在明白了。这个答案是一个部分答案,应该用MicroVirus的答案来读取。@LokiAstari是的,那些堆栈帧可能会消耗更多内存。但可能不足以填满堆。但顾名思义,堆栈帧存储在堆栈上,而这正是他耗尽内存的地方——而不是在堆上。最大堆栈大小不会根据使用情况而增长,它的限制是在编译时设置的。我怀疑他是否耗尽了堆空间。150000个浮点数是必要的大约半兆字节。没有理由在这里使用显式位大小类型(即
int32\t
):请坚持使用int,否则会持续很长时间,除非类型的宽度需要固定到某个精确的数字。@user2079303:它不会是150000个浮点数。它将是150000个堆栈帧-所有局部变量的总和+返回点OK。我现在明白了。这个答案是一个部分答案,应该用MicroVirus的答案来读取。@LokiAstari是的,那些堆栈帧可能会消耗更多内存。但可能不足以填满堆。但顾名思义,堆栈帧存储在堆栈上,而这正是他耗尽内存的地方——而不是在堆上。最大堆栈大小不会根据使用情况而增长,它的限制是在编译时设置的。