0

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

分段错误:11

每次我在参数化 Fraction 构造函数定义中调用我的简化函数后运行我的代码。这很有趣,因为当我在这个定义中调用change函数时,它被完全忽略了。我试图弄清楚如何让更改至少可以工作,这样我就可以弄清楚如何正确应用simple,但我已经做了很多年了,但我仍然不知所措。

我有三个文件:fraction.h、fraction.cpp 和 main.cpp。Main.cpp 是由我的教授编写的——这是一个创建头文件和实现文件以允许他的代码运行的作业。此特定部分的说明是:

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

//分数.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;
4

2 回答 2

1

我仔细阅读了您的代码并找出了您编写此代码的场景,您的代码中存在一些严重的问题:1-函数更改的定义必须采用以下格式:

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

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

simplify (numerator, denominator);

同样在您的简化函数中,您调用分数构造函数:

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) 会陷入无限循环。

于 2015-04-20T06:52:40.177 回答
0

在您的构造函数中,您有:

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;
  • 您的 currentsimplify基本上是一种构建器方法。你通过它nd它会为你返回一个简化Fraction的。应该是这样的方法static。您不应该simplify在构造函数内部调用,而是声明它static并像这样使用它:num1 = Fraction::simplify(1, 2);
于 2015-04-20T06:17:27.083 回答