2011-06-22 17 views
2

私はセグメンテーションフォルトを生成するプログラムに取り組んでおり、なぜそれを理解できません。 "最小"と "最大"変数からポインタ宣言を取り除いてポインタレス整数として使用すると、プログラムはうまく動作します。このポインタと整数の比較がセグメンテーションフォルトを生成するのはなぜですか?

ただし、ポインタを使用しようとすると問題が発生し、セグメント化エラーが発生します。おそらくこれはおそらく非常に簡単で十分に対処された問題であることを認識していますが、他の同様の問題を見てコードを理解しようとしました。私はまだ私の問題の解決策を見つけていない。何がうまくいかないのか分かりません。

これはコード問題を発生させる(完全なソースへのリンクは、以下である)である。

 cout << "This is the array containing the random numbers:\n"; 
for(int *i=numbers; i != numbers + arrLength; i++) { 
    if((*i % 200) == 0 && *i > 200) { 
     cin.get(); 
     cout << endl; 
    } 
    else 
     cout << *i << ' '; 

    // Get statistics 
    // In the continuation of getting, lowest, largest then adding to sum. 
    // THIS PART IS MAKING SEGMENTATION FAULT. 
    if(*i < *lowest) 
     lowest = i; 
    if(*i > *largest) 
     largest = i; 
    sum += *i; 
} 

ユーザ入力後に宣言されている古い基準にi可変ポイント:

cout << "You entered: " << arrLength << "\n\n"; 

int *numbers = new int[arrLength]; 

// Fill the array with random numbers 
srand(time(NULL)); 
int x; 
int range = 5001; 
for(int index=0; index<arrLength; index++){ 
    *(numbers + index) = rand() % range; 
    x = rand() % 2; 
    if(x > 0) { 
     *(numbers + index) = *(numbers + index) * -1; 
    } 
} 

ください私のプログラムがうまくいかず、何が間違っているのかを説明してください。

if(*i < *lowest) 
     lowest = i; 
    if(*i > *largest) 
     largest = i; 

完全なソース:この問題に関する事前の http://pastie.org/2105963

おかげで私が言ったように、以前のすべてのものは除いて動作します!

+0

を? – knittl

+0

@knittl:これはおそらくC++の宿題で、教授はポインタ計算を教えています。 –

答えて

0

0から0に初期化されていますが、逆参照はヌルポインタを介してメモリにアクセスしているため、転倒します。代わりにこれを試してみてください:

if (!lowest || *i < *lowest) 
    lowest = i; 
if (!largest || *i > *largest) 
    largest = i; 

か:あなたは代わりに配列アクセス演算子 `[インデックス]を`使用する複雑なポインタ演算を使用しない理由

int *numbers = new int[arrLength]; 
lowest = largers = numbers; // initialise to something non-null 
+0

ありがとう、今は完璧に動作し、私は間違ったことを理解します。 :) – Ms01

2

ポインタを比較しないため動作しません。プログラムに属していないメモリアドレスに格納されている値を比較しているため、SIGSEGVによって撃墜されます。

プログラムに属していないメモリにアクセスすることはできません。

3
int *largest = 0, *lowest = 0, sum = 0; 

これは問題です。メモリを割り当てたり、有効なアドレスを割り当てたりすることはありません。そして、ここで

if(*i < *lowest) //lowest is NULL 

ようにあなたは

+0

ありがとう、今は完璧に動作し、私は間違ったことを理解します。 :) – Ms01

1

lowestlargestは、それら参照を解除する前に初期化されセグメンテーションフォールト、鼻悪魔、そして何か他のものを含んで未定義の動作を取得するときにNULLポインタデリファレンス、? *lowestを使用すると、最低値が有効なアドレスを指していない場合にsegフォルトが発生します。

lowest = largest = numbers;をどこかに設定してみてください。多分それがあなたを助けるでしょう。

1

あなたのプログラミングでは、無効なメモリ(最も小さいポインタと最大のポインタ)が使用されています。 しかし、!

ポインタは、プログラムが不要な複雑性を有する実際に、このコードに

必要はありません。 インデックスを使用できるときにポインタを使用する理由

あなたの割り当て/初期化エラーはおそらく見つかりません。

for(int index=0; index<arrLength; index++){ 
    numbers[index] = rand() % range; 
    x = rand() % 2; 
    if(x > 0) { 
     numbers[index] = numbers[index] * -1; 
    } 
} 

アレイを作成するためのポインタが必要です。

int *numbers = new int[arrayLength]; 

そして最後に、あなたのプログラムが単純になります:

int lowest =numbers[0], largest = lowest; 
for(int i=0; i < arrLength; i++) { 
    int ii = numbers[i ];      ) 
    if((ii % 200) == 0 && ii > 200) { 
     cin.get(); 
     cout << endl; 
    } 
    else 
     cout << ii << ' '; 

    if(ii < lowest) 
     lowest = ii; 
    if(ii > largest) 
     largest = ii; 
    sum += ii; 
} 
+0

私は私の割り当てのためのポインタを使用する必要があります。 – Ms01

1

あなたは、有効な値にそれらを指してなくて、後でそれらを参照解除0に最低&最大値のポインタを初期化しています。

int *largest = 0, *lowest = 0, sum = 0; 
関連する問題