C++ 为什么我的程序有时会持续抛出seg错误?
我正在实现一个名为BigNum的类,该类用于处理任意大的数字。我实现它的方法是使用一个无符号整数数组,使它实际上是一个基-(2^32)数,长度为int成员 我已经让减法、乘法和所有6个比较运算符都工作了,但是模函数有时会出现分段错误 我的函数的工作方式是首先检查另一个是否至少是“this”(调用对象)的一半。如果是,它只是从中减去其他。如果不是 我正在用一个三整数长的bigNum进行测试。最显著的是1,中间是0,最不显著的是415,所以它是1*2^64+0*2^32+415*2^0,即18446744073709552031。我使用一个循环来测试我的数字对1到29之间的每个数字的模。如果第二个操作数是5、14、15、21、23或26,它总是抛出seg错误。否则,它不会抛出seg错误。我还没有检查其他人的答案是否正确 我将cout语句放在一系列行上,以缩小seg故障行的范围,这是“返回结果”行(标记如下)。我还在测试中单独使用了模数语句(与使用cout相反),它仍然抛出seg故障,因此我知道导致seg故障的不是我输出的数字 我调用下面的第一个函数,它接受一个无符号的long,然后将long转换为BigNum,然后对两个BigNum执行模运算:抛出seg错误的操作 这里是我的功能C++ 为什么我的程序有时会持续抛出seg错误?,c++,segmentation-fault,C++,Segmentation Fault,我正在实现一个名为BigNum的类,该类用于处理任意大的数字。我实现它的方法是使用一个无符号整数数组,使它实际上是一个基-(2^32)数,长度为int成员 我已经让减法、乘法和所有6个比较运算符都工作了,但是模函数有时会出现分段错误 我的函数的工作方式是首先检查另一个是否至少是“this”(调用对象)的一半。如果是,它只是从中减去其他。如果不是 我正在用一个三整数长的bigNum进行测试。最显著的是1,中间是0,最不显著的是415,所以它是1*2^64+0*2^32+415*2^0,即18446
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::运算符%(无符号长数值){//将长数值转换为一个BigNum,然后对两个BigNum执行模运算
//动态分配,因为BigNum析构函数需要它
无符号整数*部分=新的无符号整数[2];
零件[0]=(整数)编号;
零件[1]=(int)(编号>>32);
BigNum*asBig=新的BigNum(部分,2);
BigNum*result=*这个%*asBig;
删除asBig;
asBig=NULL;
返回结果;
}
BigNum*BigNum::operator%(BigNum&other){//两个BigNum。实际的模块工作吗
BigNum*结果;
BigNum*副本;
BigNum*检验;
此->simplify();//切断任何前导零整数
其他。简化();
如果(*(*this-other)数字,这个->长度);
而(*结果>其他){
结果=*结果-其他;
}
返回结果;//线路抛出seg故障
}
//如果另一个比这个小得多,那么上面的O(n)解是低效的
否则{
副本=新的BigNum(other.number,other.length);
while(true){//使“replica”等于两个可能的最高幂的“other”倍,而不超过“this”
测试=*副本*2;
如果(*测试>*此项){
打破
}
副本=测试;
}
副本=(*this)%(*replica);//副本比这个小,但副本%other==这个%other
返回(*副本%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();
BigNum::BigNum(unsigned int*,int);
BigNum*BigNum::运算符*(无符号长);
BigNum*BigNum::运算符-(BigNum&);
boolbignum::运算符<(BigNum&);
bool BigNum::operator>(BigNum&);
void BigNum::simplify();
我试着检查流氓指针,但没有看到任何指针,这些指针抛出seg故障的频率会更高,一致性也会更低。我在网上发现了堆栈损坏的想法,但这似乎只是由流氓指针引起的
我还尝试在返回之前解引用指针并计算值,但计算成功了(尽管我仍然遇到seg错误)。最后,我尝试返回其他BigNum指针,但仍然在相同的数字上出现seg错误。我看到的是损坏的堆栈吗?如果是,我将如何修复它?如果不是,是什么导致我的return语句出现seg错误?此注释:
//dynamically allocated because the BigNum destructor requires it
表示BigNum
构造函数只是将numbers
成员设置为参数,析构函数执行delete[]numbers
。但这意味着您不应该有两个具有相同数字
指针的BigNum
对象,因为当其中一个被销毁时,另一个将具有无效的数字
指针
因此,%
运算符中的这些行是一个问题:
result = new BigNum(this->numbers, this->length);
...
replica = new BigNum (other.numbers, other.length);
在使用编号之前,您需要复制编号
unsigned int *newnumbers = new numbers[this->length];
memcpy((void*)newnumbers, (void*)this->numbers, sizeof(unsigned int) * this->length);
result = new BigNum(newnumbers, this->length);
最好在
BigNum
构造函数中执行此操作,而不是要求调用方提供动态分配的数组——通常最好负责在同一模块中分配和释放内存。回答我自己的问题:
@Barmar注意到,我试图对两个不同的数字使用相同的动态分配数组,我应该更改它们。这是一个奇妙的想法,但并没有解决问题
结果是,不管出于什么原因,我的积木一开始就像
if(*(*this-other)
如果问题是7%4,则有效,但如果问题是1%5,则无效(第一个操作数必须更大,但并非总是如此)。我解决这个问题的方法是先添加一个块,然后检查第一个操作数是否已经更小。Debugger,您是否使用了调试器?如果是,在错误之前执行的最后一条语句是什么?发布一个而不是所有文本会更有帮助。请参阅。这与我有关:
result=new BigNum(This->numbers,This->length)现在您有两个BigNum
对象,它们引用同一个动态分配的数字数组。如果BigNum
析构函数删除了该数组,正如注释中所暗示的那样,那么当另一个被析构函数时,其中一个将具有无效指针。为什么要