まず、これには問題があります。
int sum_array(int num_array[]) {
int current_total = 0;
int *iptr = num_array;
while(*iptr) {
current_total += *iptr;
iptr++;
}
return current_total;
}
これが言うことは、与えられた配列の先頭から開始することです。int のサイズのメモリ ブロックの値がゼロでない間、次のメモリ ブロックに移動します。ここで何が起こるかというと、配列の末尾を超えて進み続け、最終的にメモリをいじってはいけません。これがセグメンテーション フォールトの原因です。ランダムに見える理由は、配列の末尾のメモリが空である場合があり、これで問題なく動作するからです。しかし、そうでない場合もあり、アクセスしてはならないメモリにアクセスしてクラッシュします。
それが唯一の問題ではないかもしれませんが、私が最初に気づいた問題でした。これを修正するには、配列のサイズを追跡し、それを関数に渡し、ポインタを使用するのではなく、for ループを使用して反復します。このような:
int sum_array(int num_array[], int arraySize) {
int current_total = 0;
for(int i = 0; i < arraySize; i++) {
current_total += num_array[i];
}
return current_total;
}
また何かないか探してみます。
編集:
もう一度見てみると、他の 2 つの場所で同じことを行っています。ここ:
while(*prime) {
cout << *prime << " ";
prime++;
}
そしてここ:
while(*prime) {
*prime = 0;
prime++;
}
どちらの場所でも、アレイをオーバーランしているドーナツにドルを賭けます。それがセグメンテーション違反の原因です。あなたが初めての場合は、ポインター演算を使用して配列をトラバースしないことを強くお勧めします。古き良き for ループに固執し、for ループの最後を追跡します。
他の人々は、スタックの代わりにヒープから配列を割り当てることを提案しています。これは巨大な配列の場合は良い考えですが、少なくとも私の経験では、スタック オーバーランが通常セグメンテーション違反を引き起こすことはありません。通常、スタック内よりも多くのスペースを割り当てると、コンパイラはそれを認識します。それでも、ベクトルを使用することをお勧めします (宿題に大きなクレジットを追加するには、ヒープからポインターの配列として割り当てられた二重ポインターを使用して独自のベクトルを実装する方法を理解できるかどうかを確認してください;)) または単に std を使用します。 :ベクター。これは拡張可能な配列であり、必ずしも必要ではない大量のスペースを割り当てるのではなく、見つけたときに配列に素数を追加できます。