Ошибка получения ошибки сегментации после вызова функции в определении конструктора?

Я исследовал эту ошибку, и она кажется обычной для опасного выделения памяти или перегрузки, но я не могу найти, где это применимо к моему коду. В основном я продолжаю получать сообщение об ошибке:

Ошибка сегментации: 11

каждый раз, когда я запускаю свой код после вызова моего упростить функция в определении параметризованного конструктора Fraction. И это смешно, потому что, когда я звоню менять Функция внутри этого определения, она полностью игнорируется. Я пытаюсь понять, как получить менять по крайней мере, чтобы я мог понять, как правильно применять упростить, но я был в этом целую вечность и все еще в растерянности.

У меня есть три файла: фракция.h, фракция.cpp и main.cpp. Main.cpp был написан моим профессором — это задание для создания заголовочных файлов и файлов реализации, позволяющих запускать его код. Инструкции для этой конкретной части:

Закрытая функция-член упростить что уменьшает долю до
его самые низкие сроки (12/15 => 4/5). Если вы пишете функцию, вы должны вызвать упростить функция в определении параметризованного конструктора, так что функция создается в упрощенном виде.

//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;

0

Решение

Я точно прочитал ваш код и выяснил ваш сценарий написания этого кода,
в вашем коде есть серьезные проблемы:
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 во временной переменной перед d = n;

в противном случае следующая команда (r = d;) будет эквивалентна по r = n;

Вы должны решить эту логическую ошибку для решения ошибки фрагментации.
эта ошибка вызвана в этом случае:

когда программа использует большой объем кучи, превышающий допустимый объем использования кучи.
в некоторых случаях генерация объекта или получение памяти (alloc | malloc) попадают в бесконечный цикл.

1

Другие решения

В вашем конструкторе у вас есть:

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 в основном метод строителя. Вы передаете это n а также d и возвращает упрощенный Fraction для тебя. Такие методы должны быть static, Вы не должны звонить simplify внутри конструктора, но вместо этого объявить его static и используйте это так: num1 = Fraction::simplify(1, 2);
0