Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么我的程序有时会持续抛出seg错误?_C++_Segmentation Fault - Fatal编程技术网

C++ 为什么我的程序有时会持续抛出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的类,该类用于处理任意大的数字。我实现它的方法是使用一个无符号整数数组,使它实际上是一个基-(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错误的操作

这里是我的功能

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
析构函数删除了该数组,正如注释中所暗示的那样,那么当另一个被析构函数时,其中一个将具有无效指针。为什么要