【问题标题】:Segmentation fault for higher values of n(e.g n=999997)较高 n 值的分段错误(例如 n=999997)
【发布时间】:2020-06-21 18:25:56
【问题描述】:

我正在使用动态编程来解决一个问题,其中我将得到 n 并且需要通过使用这三个操作(-1、/2、/3)输出最小数量的操作以从 n 中获得 1。给定约束(1 我的代码给出了 segmentation fault(在求解函数中的某处),以获得更高的 n 值(例如 977775,1000000),但在较小的输入(例如 100000)下运行良好。 我已经尝试了很多,但我无法在我的代码中找到问题。还有其他方法可以在这个问题中应用动态编程。 任何帮助将不胜感激。

#include<iostream>
using namespace std;
int solve(int n,int a[])
{
    if(n==1)
    return 0;
    if(a[n]!=-1)
    return a[n];
    int ans=100000;
    for(int i=0;i<3;i++)
    {
        if(i==0)
        {
            a[n]=solve(n-1,a)+1;
            if(a[n]<ans)
            ans=a[n];
        }
        else if(i==1 && n%2==0)
        {
            a[n]=solve(n/2,a)+1;
            if(a[n]<ans)
            ans=a[n];
        }
        else if(i==2 && n%3==0)
        {
            a[n]=solve(n/3,a)+1;
            if(a[n]<ans)
            ans=a[n];
        }
    }
    return ans;
}
int main()
{
    int n;
    cin>>n;
    int a[n+1];
    for(int i=0;i<=n;i++)
    a[i]=-1;
    int ans=solve(n,a);
    cout<<ans<<endl;
    return 0;
}

【问题讨论】:

  • int a[n+1]; 是一个可变长度数组,是标准 C++ 的一部分。我只知道一个支持它的编译器。您是否知道 VLA 的内存是在堆栈上分配的?那是你的问题。堆栈大小太小。使用堆内存。
  • 可能是堆栈溢出。请考虑使用std::vector&lt;int&gt; a(n+1); 而不是int a[n+1];
  • 原因可能是递归调用函数过多导致堆栈溢出。如果是这种情况,使用std::vector 将无法解决此问题。
  • 使用向量仍然会导致溢出。 @ThomasSablik 我改用了 int *a = new int[n+1] 但它仍然显示分段错误。还有什么我可以做的吗?
  • 正如@MikeCAT 暗示的那样,问题可能与您的函数过于频繁地递归调用自身有关。使用 std::vector 本身并不能解决这个问题。但是,如果您确实使用vector,请务必将其作为参数通过引用(使用int solve(int n, vector&lt;int&gt;&amp; a) - 注意&amp;),否则,每次调用都会复制整个向量。

标签: c++ segmentation-fault dynamic-programming


【解决方案1】:

问题是 C++ 中的 int 变量最多只能存储 8 位数字,我会从 int ans 切换到 double ans 来解决问题,还要记住 double 最多可以存储 34 位数字,如果您尝试存储比最大允许位数更多的数字,发生奇怪的事情,在这种情况下,您会得到一个 stackOverflow .....还要考虑以下事项:在您的函数中,您正在调用大约 999997 次递归调用 * 3这大约是堆栈的 3000000 次递归调用,这将使用太多的内存,因此会出现分段错误.....

【讨论】:

  • 一个 IEEE-754 double 可以存储约 17 位数字。我想你的意思是long long int
  • 哦,是的,我意识到了这一点。有没有其他方法可以在这个问题中应用动态编程。也很抱歉,但问题中的约束是 1
  • “在 C++ 中,一个 int 变量最多只能存储 8 位数字”在 int 是 32 位有符号整数的典型环境中是不正确的,它可以存储高达 2**31 - 1 = 2147483647 的整数。在这种情况下,所有 9 位整数都可以存储在 int 变量中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多