繁体   English   中英

Segmentation Fault C ++(数组太大?)

[英]Segmentation Fault C++ (array too large?)

我正在研究项目Euler 问题14 ,在这里我需要找到1,000,000以下最长的collat​​z序列。 我想出了一种适用于较小数字(例如100)的算法,该算法将1-100中的每个collat​​z数字存储到一个数组中,并使用该数组作为参考来加快较高数字的计算速度。 我的代码如下:

#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之后出现了段错误。 通过调试,我发现段错误发生的速度取决于数组y的大小,因此我假设数组太大。 从对段错误的(基本)理解上,我认为我只是在访问“不被允许”的内存。 我有什么办法可以解决这个问题,还是我应该开始着手解决这个问题的另一种方法? 我正在Ubuntu Studio上使用g ++进行编译。

对于您系统的默认堆栈大小,此数组可能太大。 最简单的解决方法是将其定义更改为:

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

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

对于N下的起始数字,collat​​z序列可以超出N 对于N == 1000000考虑x == 333335

我建议您将y设为vector<int>并动态扩展它,或者只是使其变为unordered_map<int, int>

如果y对于您的堆栈太大,则在main尝试运行时,您将获得堆栈溢出异常。

您的问题很可能是a大于y的大小。 当我通过调试器运行它时,当x为4255时, a为1417174,因此您的算法可能有问题。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM