簡體   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