分段故障C ++(数组太大?)

时间:2014-09-28 00:17:19

标签: c++ arrays segmentation-fault

我正在研究Euler项目Problem 14,我需要找到1,000,000以下最长的文件序列。我想出了一个适用于较小数字(例如100)的算法,该算法将每个1到100的整数数据存储到一个数组中,并使用该数组作为参考来加速更高数字的计算。 我的代码如下:

#include <iostream>
using namespace std;

long even(long n){ //the even-collatz function
    n=n/2;
    return n;
}

long odd(long n){ //the odd collatz function
    n=3*n+1;
    return n;
}

int main(){
    long  x, c=0, y[1000000]; // x= the number we are finding the collatz number of, c a counter that keeps track of how many steps we've taken in the sequence, y is an array to store the collatz numbers.

    for (x=1; x<1000000; x++){ //iterates from x=1 to 1 million
            long a = x;     //sets a number a equal to the number we are currently trying to find the collatz number of
            long b = a;     
            c=0;                    //intializes counter at 0 
            while (a!=0){           //loops infinitely; the only way to exit is through a break.
                    if (a%2==0){    // detects if the number is even
                            a=even(a);      //applies the even-collatz function if so; sets x=x/2
                            c=c+1;
                            if (y[a]!=0){   // checks if the collatz number of x is already discovered
                                    y[b]=c+y[a]; //adds the current number of steps to the collatz number of x and 
                                    break;  //exits the while loop
                            }

                    }
                    else if (a==1){         //checks if the new x is equal to one and
                            y[b]=c;         //if it is, it writes the current value of c to y[b] and
                            break;          // exits the loop
                    }
                    else if (a%2==1){       //same as the "even" block, except for odd numbers 

                            a=odd(a);
                            c=c+1;
                            if( y[a]!=0){
                                    y[b]=c+y[a];
                                    break;
                            }

                    }
            //this is the end of the while loop; we've applied the collatz function as many times as we've needed to to x, and incremented the counter each time
            }
  }

    long z;
    for (int n=0;n!=100;n++){
            if (y[n+1]>y[n]){
                    z=y[n+1];
            }
    }
    cout << z << "\n";


}

我遇到的问题是在for循环中我在x = 1818之后得到了段错误。通过调试,我发现segfault发生的速度取决于数组y的大小,所以我假设数组太大了。根据我对segfaults的基本理解,我认为我只是在访问我“不被允许”的内存。有什么方法可以绕过这个,或者我应该开始努力解决这个问题?我在Ubuntu studio上使用g ++进行编译。

3 个答案:

答案 0 :(得分:5)

这个数组对于你系统的默认堆栈大小来说可能太大了;最简单的解决方法是将其定义更改为:

std::vector<long> y(1000000);

其他一切都可以保持不变。您可以在循环中稍后使用y.size()代替幻数1000000

答案 1 :(得分:0)

对于N下的起始号,拼贴顺序可以超出N。对于N == 1000000,请考虑x == 333335

我建议您将y设为vector<int>并动态展开,或者只设unordered_map<int, int>

答案 2 :(得分:-1)

如果y对于您的堆栈来说太大,那么只要main尝试运行就会出现堆栈溢出异常。

a的问题更有可能超过y的大小。 当我通过调试器运行时,ax为4255时为1417174,因此您的算法可能存在问题。

也就是说,您应该自己分配它,或者将其设置为静态,因为无法保证Project Euler使用的任何编译器都允许这么大的堆栈大小。