2010-11-23 14 views
2

私はシンプルなC++プログラムを用意しています。このプログラムは、intで構成された配列に対して2つのソートアルゴリズムを実行し、それぞれの時間を追跡します。かなり基本的ですが、問題に遭遇しました。私はsegfaultの原因を知っていますが、なぜですか?

プログラムが最初に起動すると、配列内にいくつの項目を表示するかが尋ねられます。私の任務は、100個のアイテムから750000までの特定の長さの配列を設定することです。これは、最大600000を含む多くの値を処理します。しかし、私は750000を試してみるとすぐにsegfaultsします。ここのカップルで、4番目の配列(すべて同じ長さ)が初期化されたときにエラーが発生することがわかりました。奇妙なことは、OS上でのみ起こることです。私の学校では問題はありません。 (私の学校ではredhatを使用しながら、私は、最新のUbuntuの上だよそれが役に立つかどうかわからない。)

私はちょうど参照の完全なコードが含まれますが、セグメンテーション違反が27行で発生します。

int array1[num], array2[num], array3[num], array4[num]; // initialize arrays 

私は私は別々の行に各配列を初期化し、その間に呪文を入れたので、これを知ってください。 array1,2,3が初期化された後、segfaultsされます。この場合も、配列が約600000程度以上の場合にのみ発生します。何でもうまく動作しません。

全コード:

#include <iostream> 
#include <cstdlib> 
#include <ctime> 

using namespace std; 

void insertionSort(int array[], int size); 
void bubbleSort(int array[], int size); 
void mergeSort(int array[], int first, int last, int size); 
void quickSort(int array[], int size); 

int main() 
{ 

    cout << endl << endl << "\t\t**** Extra Credit Assignment- Sorting ****" << endl << endl << endl; 
    cout << "Enter the number of items to sort: "; 
    int num; 
    cin >> num; 
    while(cin.fail()) // while cin does not recieve an integer 
    { 
     cin.clear(); 
     cin.ignore(1000, '\n'); 
     cout << "Invalid entry. Try again: "; // try again 
     cin >> num; 
    } 

    int array1[num], array2[num], array3[num], array4[num]; // initialize arrays 

    int randNum, sizeOfArray = sizeof(array1)/sizeof(array1[0]); // random number, size of the arrays 
    srand(time(NULL)); // random seed (used with rand()) 

    for(int i = 0; i < sizeOfArray; i++) // traverse through the array 
    { 
     randNum = rand() % 2147483647+1; // establish random number (from 1 to 2147483647) 
     array1[i] = array2[i] = array3[i] = array3[i] = randNum; // set randNum to all arrays at current index 
    } 

    time_t beginTime, endTime; 
    double elapsedTime; 

    cout << endl << "Elapsed time:" << endl << "\tInsertion Sort-\t"; 

    time(&beginTime); 
    insertionSort(array1, sizeOfArray); 
    time(&endTime); 

    elapsedTime = difftime(endTime, beginTime); 
    cout << elapsedTime << " seconds" << endl << "\tBubble Sort-\t"; 

    time(&beginTime); 
    bubbleSort(array2, sizeOfArray); 
    time(&endTime); 

    elapsedTime = difftime(endTime, beginTime); 
    cout << elapsedTime << " seconds" << endl << "\tMerge Sort-\t"; 

    time(&beginTime); 
    mergeSort(array3, 0, sizeOfArray-1, sizeOfArray); 
    time(&endTime); 

    elapsedTime = difftime(endTime, beginTime); 
    cout << elapsedTime << " seconds"<< endl; 





/* ********************* TESTING ************************* 
// ******************************************************* 

    cout << "Insertion->Unsorted:\t"; 
    for(int i = 0; i < sizeOfArray; i++) 
    { 
     cout << array1[i] << " "; 
    } 
    cout << endl; 

    insertionSort(array1, sizeOfArray); 

    cout << "Insertion->Sorted:\t"; 
    for(int i = 0; i < sizeOfArray; i++) 
    { 
     cout << array1[i] << " "; 
    } 
    cout << endl; 




    cout << "Bubble->Unsorted:\t"; 
    for(int i = 0; i < sizeOfArray; i++) 
    { 
     cout << array2[i] << " "; 
    } 
    cout << endl; 

    bubbleSort(array2, sizeOfArray); 

    cout << "Bubble->Sorted:\t\t"; 
    for(int i = 0; i < sizeOfArray; i++) 
    { 
     cout << array2[i] << " "; 
    } 
    cout << endl; 




    cout << "Merge->Unsorted:\t"; 
    for(int i = 0; i < sizeOfArray; i++) 
    { 
     cout << array3[i] << " "; 
    } 
    cout << endl; 

    mergeSort(array3, 0, sizeOfArray-1, sizeOfArray); 

    cout << "Merge->Sorted:\t\t"; 
    for(int i = 0; i < sizeOfArray; i++) 
    { 
     cout << array3[i] << " "; 
    } 
    cout << endl; */ 

    return 0; 
} 

void insertionSort(int array[], int size) 
{ 
    for(int i = 1; i < size; i++) 
    { 
     int item = array[i], index = i; 
     while(index > 0 && array[index-1] > item) 
     { 
      array[index] = array[index-1]; 
      index--; 
     } 
     array[index] = item; 
    } 
} 

void bubbleSort(int array[], int size) 
{ 
    bool sorted = false; 
    for(int i = 1; i < size && !sorted; i++) 
    { 
     sorted = true; 
     for(int i2 = 0; i2 < size-i; i2++) 
     { 
      int nextI = i2+1; 
      if(array[i2] > array[nextI]) 
      { 
       swap(array[i2], array[nextI]); 
       sorted = false; 
      } 
     } 
    } 
} 

void merge(int array[], int first, int mid, int last, int size) 
{ 
    int tempArray[size]; 
    int first1 = first, first2 = mid+1; 
    int last1 = mid, last2 = last; 
    int index = first1; 

    while(first1 <= last1 && first2 <= last2) 
    { 
     if(array[first1] < array[first2]) 
     { 
      tempArray[index] = array[first1]; 
      first1++; 
     } 
     else 
     { 
      tempArray[index] = array[first2]; 
      first2++; 
     } 
     index++; 
    } 
    while(first1 <= last1) 
    { 
     tempArray[index] = array[first1]; 
     first1++; 
     index++; 
    } 
    while(first2 <= last2) 
    { 
     tempArray[index] = array[first2]; 
     first2++; 
     index++; 
    } 

    for(index = first; index <= last; index++) 
    { 
     array[index] = tempArray[index]; 
    } 
} 

void mergeSort(int array[], int first, int last, int size) 
{ 
    if(first < last) 
    { 
     int mid = (first+last)/2; 
     mergeSort(array, first, mid, size); 
     mergeSort(array, mid+1, last, size); 
     merge(array, first, mid, last, size); 
    } 
} 

すべてのヘルプは大歓迎です。私のシステムにはメモリの制限がありますか?私は本当にただの考えを知っていません。

+0

それを上げることができます参照してください:http://stackoverflow.com/questions/408670/stack-static-and-heap-in-c –

答えて

2

他にも触れられているように、SEGVはスタックのオーバーフローによるものです。あなたの学校のレッドハットマシンではなくあなたのubuntuマシンで起こる理由は、デフォルトのスタックサイズの違いによるものと思われます。

デフォルトのスタックサイズをulimit -sに変更することができます。追加の引数はなく、現在のスタックサイズをキロバイト単位で出力します。たとえば、私のマシンでは、8192または8メガバイトを出力します。私は多分...(あなたが持っているように)12メガバイトが必要になりますので、4つの、配列、スタック領域の3メガバイト(int型あたり4バイト)について必要になりますulimit -s 16384

750000個のintの配列と16メガバイトに

+0

感謝します!完璧に働いた。新しい端末を開くたびに設定しなければならないことに気付きました。 16メガバイトのスタックサイズを永久に設定する方法はありますか? – JoeC

+2

これは問題のスケーラブルな解決策ではなく、正しく動作するようにコードを修正してください。 –

+0

@JoeC、ulimitを.bashrcやその他のシェル起動ファイルに入れることができます(使用するシェルに応じて) –

6

あなたが固定サイズに制限があり、スタックの上にこのような大きな配列を割り当てることができない、試してみてください。

int* array1 = new int[num]; 
+0

ありがとう、私はそれを試みるかもしれません。つまり、残りの関数を編集して、実際の配列の代わりに配列へのポインタをとらなければならないということです。 ; /どのように3つの大きな配列が割り当てられますが、それは4番目の配列で失敗しますか?その限界を広げる方法はありますか? – JoeC

+0

配列の前にキーワードstaticを追加するだけです。それはメモリをヒープに移動します。 –

+0

いいえ、任意のint *を配列として扱うことができます。それを試してみてください! –

2

あなたは、スタック上の非常に大きな配列を割り当てられてきた、あなたは、スタックをオーバーフローしています。それらを新規作成したり静的にすると、ヒープに割り当てられ、失敗しません。

+0

私はこのアイデアが好きですが、今は "ExCred.cpp:28:error: 'array1'の記憶容量が定数ではありません numの代わりにconst intが宣言されています。何か案は? – JoeC

1

これは、スタックが無限のリソースではないためです。 int x[big_honkin_number]を実行すると、その配列のスタックに十分な領域を割り当てようとします。

通常はコードをコンパイル/リンクしてスタックを増やすことができますが、動的メモリ割り当て(つまり、new)を使用する方が良い解決策です。

関連する問題