调用构造函数定义中的函数后收到Segmentation Fault 11错误



我研究过这个错误,它似乎在危险的内存分配或过载中很常见,但我找不到它适用于我的代码。基本上我一直收到错误消息:

分段故障:11

每次在参数化Fraction构造函数定义中调用simple函数后运行代码时。这很有趣,因为当我在这个定义中调用change函数时,它被完全忽略了。我正在想办法让更改至少起作用,这样我就可以想办法正确应用简化,但我已经做了很长时间了,仍然不知所措。

我有三个文件:fraction.h、fraction.cpp和main.cpp。main.cpp是我的教授写的——这是一项创建头文件和实现文件的任务,以允许他的代码运行。该特定部分的说明如下:

一个名为simple的私有成员函数,它将分数减少到其最低项(12/15=>4/5)。如果编写该函数,则应在参数化构造函数定义中调用simple函数,以便以简化的形式创建该函数。

//fraction.h:

#ifndef FRACTION_
#define FRACTION_
#include <stdio.h>
#include <iostream>
#include <math.h>
using namespace std;
class Fraction {
private:
int numerator;
int denominator;
int change (int a, int b);
Fraction simplify (int n, int d);
public:
Fraction();
Fraction (int num, int denom);
Fraction sumWith (Fraction a);
Fraction multiplyWith (Fraction z);
void const print (ostream & out) const;
};
#endif /* defined(____Fraction__) */

//fraction.cpp[排除不受影响的函数]:

#include "fraction.h"
#include <iostream>
#include <math.h>
using namespace std;
int Fraction::change(int a, int b){
int temp;
temp = a;
a = b;
b = temp;
return temp; }
Fraction Fraction::simplify (int n, int d){
int r, gcd, true_n, true_d, q;
true_n = n;
true_d = d;
if ((n) < (d)){
change (n, d);
q = 5; }
r = (n % d);
if ((r != 1) && (r != 0)){
for (int i = 0; r > 1; i++){
r = (n % d);
d = n;
r = d;
i++; }
if (r == 0){
gcd = n;
n = true_n/gcd;
d = true_d/gcd; }
else {
n = true_n;
d = true_d; }
}
if (r == 0){
n = n/d;
d = 1; }
if (q == 5){
change (n, d); }
return Fraction(n, d); }
Fraction::Fraction() {
numerator = 1;
denominator = 1; }

Fraction::Fraction (int num, int denom) {
if (denom == 0) {
cerr << "Denominator may not be 0.";
exit (EXIT_FAILURE); }
else {
numerator = num;
denominator = denom; }
if (denominator < 0){
denominator = denominator * -1;
numerator = numerator * -1; }
simplify (numerator, denominator);
}

//main.cpp的适用摘录:

void outputExpression(ostream & out,
const Fraction & num1,
const Fraction & num2,
const Fraction & result,
bool isSum);
int main() {
Fraction num1, num2, result;
num1 = Fraction(1, 2);
num2 = Fraction(2, 3);
result = num1.sumWith(num2);
outputExpression(cout, num1, num2, result, true);
result = num1.multiplyWith(num2);
outputExpression(cout, num1, num2, result, false);
cout << endl;

我准确地阅读了您的代码,并找到了编写此代码的场景,您的代码中存在一些严重问题:1-功能更改的定义必须采用以下格式:

int Fraction::change(int* a, int* b){
int temp;
temp = *a;
*a = *b;
*b = temp;
return *temp; }

2-在您的构造函数中,您调用simple函数

simplify (numerator, denominator);

同样在您的simple函数中,您可以调用分数构造函数:

simplify (numerator, denominator);

它是一个无限循环,会导致堆空间的过度使用(超出一个程序使用堆的法定数量)。

3-在简化函数中,您写道:

if ((r != 1) && (r != 0)){
for (int i = 0; r > 1; i++){
r = (n % d);
d = n;
r = d;
i++; }

这是一个问题,因为必须在d=n之前将d保存在临时变量中;

否则,下一个命令(r=d;)将等价于r=n;

必须解决这个逻辑错误才能解决碎片错误。这种情况下导致的错误:

当程序使用的堆空间大于其合法堆使用量时。在某些情况下,生成对象或获取内存(alloc|malloc)属于无限循环。

在构造函数中,您有:

Fraction::Fraction (int num, int denom) {
// ...
simplify (numerator, denominator);
}

然后,在simplify中,您有:

Fraction Fraction::simplify (int n, int d){
// ...
return Fraction(n, d);
}

这是一个无限循环。

你可以用两种方法之一来修复它:

  • 如果您不想允许未简化的分数,那么让simplify修改对象,而不是返回新的对象

如下:

numerator = n;
denominator = d;
  • 您当前的simplify基本上是一个构建器方法。您向它传递一个nd,它会为您返回一个简化的Fraction。此类方法应为static。您不应该在构造函数内部调用simplify,而应该声明它为static,并像这样使用它:num1 = Fraction::simplify(1, 2);

最新更新