私はBigNumという名前のクラスを実装しています。私が実装した方法は、符号なし整数の配列を使用して、長さのintメンバーを使用して、それを事実上ベース(2^32)数にしています。なぜ私のプログラムは時々seg-faultsを投げつけていますか?
私は減算、乗算、および6つの比較演算子のすべてを動作させましたが、モジュラス関数は時々セグメンテーションフォールトを投げます。
私の関数が動作する方法は、まず、 "this"(呼び出し元のオブジェクト)の少なくとも半分であるかどうかを調べることです。そうであれば、それは単にこれから他を差し引くだけです。そうでない場合は、
私は3つのintsのbigNumでテストしています。最も重要なものは1、中央のものは0、最下位のものは415なので、1 * 2^64 + 0 * 2^32 + 415 * 2^0です。これは18446744073709552031です。第2オペランドが5,14,15,21,23、または26の場合、常にseg-faultがスローされます。それ以外の場合は、決してseg-faultをスローしません。私は答えが他の人に正しければまだチェックしていない。
私は、seg-fault行を絞り込むために一連の行にcout文を入れました。これは "return result"(以下に記された行)でした。私はモジュラスステートメントだけを私のテストに入れました。(それはcoutを使うのとは対照的ですが)それでもseg-faultを投げたので、seg-faultの原因となった番号を出力していないことが分かりました。
私はunsigned longを取って、次にlongをBigNumに変換し、次に2つのBigNumでモジュラスを実行します:seg-faultを投げる操作。ここで
ここに私の機能
BigNum *BigNum::operator% (unsigned long number) { //converts the long to a BigNum, then performs modulus on two BigNums
//dynamically allocated because the BigNum destructor requires it
unsigned int *parts = new unsigned int [2];
parts [0] = (int) number;
parts [1] = (int) (number >> 32);
BigNum *asBig = new BigNum (parts, 2);
BigNum *result = *this % *asBig;
delete asBig;
asBig = NULL;
return result;
}
BigNum *BigNum::operator% (BigNum& other) { //two BigNums. Does the actual modular work
BigNum *result;
BigNum *replica;
BigNum *test;
this->simplify(); //cuts off any leading zero ints
other.simplify();
if (*(*this - other) < other) { //if other is less than half of this
result = new BigNum(this->numbers, this->length);
while (*result > other) {
result = *result - other;
}
return result; //line throwing seg-fault
}
//if other is significantly smaller than this, the O(n) solution above is inefficient
else {
replica = new BigNum (other.numbers, other.length);
while (true) { //makes "replica" equal "other" times the highest power of two possible without exceeding "this"
test = *replica * 2;
if (*test > *this) {
break;
}
replica = test;
}
replica = (*this) % (*replica); //replica is smaller than this, but replica%other == this%other
return (*replica % other);
}
}
は、私はそこに呼び出されるすべての関数のプロトタイプされています。
BigNum::BigNum (unsigned int*, int);
BigNum *BigNum::operator* (unsigned long);
BigNum *BigNum::operator- (BigNum&);
bool BigNum::operator< (BigNum&);
bool BigNum::operator> (BigNum&);
void BigNum::simplify();
私は不正なポインタをチェックしようとしたが、任意のを見ていない、とそれらはより多くの頻繁かつ少ない一貫SEG-障害をスローしていました。私は、オンラインでスタック破損のアイデアを見つけましたが、それは不正なポインタが原因であるようです。
私はまた、ポインタの逆参照を試みて戻り値の直前に値を取り戻しました。そして、coutは機能しました(私はまだsegフォルトがあります)。最後に、他のBigNumポインタを返そうとしましたが、同じ数字にseg-faultがあります。私は破損したスタックを見ていますか?もしそうなら、どうすれば修正できますか?そうでなければ、私のreturn文がseg-faultになる原因は何ですか?
デバッガ、デバッガを使用しましたか?もしそうなら、障害の前に実行された最後のステートメントは何ですか? –
すべてのテキストの代わりに[mcve]を投稿すると便利です。 See [ask]。 –
これは私にとって心配です: 'result = new BigNum(this-> numbers、this-> length);'動的に割り当てられた同じ配列を参照する2つの 'BigNum'オブジェクトがあります。 'BigNum'デストラクタがコメントに暗示されているように配列を削除した場合、一方が破壊されたときにそのポインタの1つが無効なポインタを持ちます。 – Barmar