为什么我的程序总是出现分段错误?
Why is my program throwing seg-faults sometimes and consistently?
我正在实现一个名为BigNum的类,用于处理任意大的数字。我实现它的方式是使用一个无符号整数数组,使其有效地成为一个基数-(2^32)数,长度为int成员。
我已经得到减法,乘法和所有6个比较操作符工作,但模函数有时抛出分割错误。
我的函数的工作方式是首先,检查other是否至少是"this"(调用对象)的一半。如果是,它只是从这个减去其他。如果不是,
我正在测试一个长为3 int的大整数。最高有效的是1,中间是0,最低有效的是415,所以是1*2^64+0*2^32+415*2^0,就是18446744073709552031。我使用了一个循环来测试我的数字模取1到29之间的每个数字。如果第二个操作数是5、14、15、21、23或26,它总是抛出一个段错误。否则,它永远不会抛出隔离错误。我还没有检查这些答案是否正确。
我将cout语句放在一系列行中以缩小分段错误线,它是"返回结果"行(如下所示)。我还在测试中单独使用了模数语句(而不是使用cout),它仍然抛出了segfault,所以我知道不是我输出的数字导致了segfault。
我调用下面的第一个函数,它接受一个unsigned long,然后将long转换为一个BigNum,然后对两个BigNum执行模数:该操作抛出segfault。
下面是我的函数
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();
我试着检查流氓指针,但没有看到任何,这些会更频繁地抛出segfault,不太一致。我在网上找到了堆栈损坏的想法,但这似乎只是由一个流氓指针引起的。
我还尝试在返回之前解引用指针和计数值,并且计数工作(尽管我仍然得到了一个段错误)。最后,我尝试返回其他BigNum指针,并且仍然在相同的数字上得到一个segfault。我看到的是一个损坏的堆栈吗?如果是这样,我该如何解决?如果不是,是什么导致我的返回语句出现分段错误?
注释:
//dynamically allocated because the BigNum destructor requires it
表示BigNum
构造函数仅仅将numbers
成员设置为实参,而析构函数将delete [] numbers
成员设置为实参。但这意味着你不应该有两个具有相同numbers
指针的BigNum
对象,因为当其中一个被销毁时,另一个将具有无效的numbers
指针。
所以%
操作符中的这几行是一个问题:
result = new BigNum(this->numbers, this->length);
...
replica = new BigNum (other.numbers, other.length);
你需要在使用numbers
之前复制它们。
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注意到我试图为两个不同的数字使用相同的动态分配数组,我应该改变它们。这是个好主意,但并不能解决问题。
结果是,不管什么原因,我的block以
开头 if (*(*this - other) < other) {
可以工作,但如果是1%5就不行(第一个操作数必须更大,但并不总是这样)。我解决这个问题的方法是在前面添加一个块,检查第一个操作数是否已经更小了。
- 在某些循环内使用vector.push_back时出现分段错误
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 当我的阵列太大时出现分段错误
- 分段错误当我试图运行程序时出错
- 在c++中初始化矩阵时出现分段错误(核心转储)
- 尝试使用集合函数时出现分段错误
- 我无法缩小此分段错误的原因
- g++的分段错误(在NaN上使用to_string两次时)
- 我是如何在这段代码中出现分段错误的
- 创建结构的数组时遇到分段错误
- 在c++中键入向量中的所有值后,得到分段错误(核心转储)
- 在 c++ 中实现 Trie 时出现分段错误
- 为什么 fstream 在打开带有格式的文件时会导致分段错误?
- 为什么我遇到分段错误?
- 动态类的分段错误(家庭作业问题)
- 分段错误 - 读取初始化指针的数组
- 如何摆脱C ++中的分段错误错误?
- 使用 CTYPE 时出现分段错误
- 为什么代码给出分段错误?