【问题标题】:Segmentation fault in a massively recursive function大规模递归函数中的分段错误
【发布时间】:2015-10-07 16:59:35
【问题描述】:

我有一个函数可以调用自己几乎无限次,但它确实有一个结束。它计算数学公式(在 TeX 中):

x<a:

g_{a}(x)=1

x>=a:

g_{a}(x)=g_{a}(x-1)+g_a(x-a)

这是我的代码(c++):

#include <iostream>
#include <math.h>
#include <stdio.h>
#include <cmath>
using namespace std;
double g( double a, double x){
    if (x>=a) return (g(a,x-1)+g(a,x-a));
    else if (x<a) return 1;
    return 0;
}
int main(){cout << g(sqrt(10000019),10000019);}

我用g(sqrt(10000019),10000019);调用函数 如何停止 SEGFAULT?

【问题讨论】:

  • 你得到 SEGFAULT 的 a 和 x 的值是多少?
  • 另外,你不能发一个MCVE吗?
  • 顺便说一句,它是 Ackermann_function,我说的对吗?如果是,那么我怀疑你可以停止 SEGFAULT。
  • @Adel 编辑调用
  • @Fabio 这不是 MCVE 吗?

标签: c++ math


【解决方案1】:

我怀疑您的 seg-fault 是由于堆栈空间不足。

您可以限制/无限制堆栈空间的大小(至少在 Linux 上) 使用 tcsh 的 limit 命令。

 % limit 
cputime      unlimited
filesize     unlimited
datasize     unlimited
stacksize    10240 kbytes
coredumpsize 0 kbytes
memoryuse    unlimited
vmemoryuse   unlimited
descriptors  4096 
memorylocked 64 kbytes
maxproc      1024 

然后你就可以不限制你的堆栈大小了

% unlimit stacksize
% limit

cputime      unlimited
filesize     unlimited
datasize     unlimited
stacksize    unlimited
coredumpsize 0 kbytes
memoryuse    unlimited
vmemoryuse   unlimited
descriptors  4096 
memorylocked 64 kbytes
maxproc      1024 

再试一次。

【讨论】:

  • 内存用完还是会崩溃--
  • 是的,但他可能会为了他的目的而做到这一点。另一种解决方案是缓存/记忆小的值,因此它不需要做太多的递归。
【解决方案2】:

我有一个函数可以调用自己几乎无限次,但它确实有结束。

你有近乎无限的堆栈内存吗?

如果不是(可能的情况),您将很快粉碎您的筹码。分段错误是一个明显的迹象。

我会完全避免递归。

【讨论】:

  • 那么我如何将其转换为迭代?
  • @KaidenPrince:用你的手指……?我不明白你的问题。
  • 我真的不知道如何转换它,否则我会的。
  • 您也可以尝试将其转换为尾递归。然后优化器会命中它并为你把它变成迭代。
  • @CrazyEddie 会尝试的。稍后发布更新。 GCC 会优化这个吗?
猜你喜欢
  • 2021-05-23
  • 2013-03-05
  • 2014-11-05
  • 2019-11-16
  • 2017-12-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多