Я исследовал эту ошибку, и она кажется обычной для опасного выделения памяти или перегрузки, но я не могу найти, где это применимо к моему коду. В основном я продолжаю получать сообщение об ошибке:
Ошибка сегментации: 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;
Я точно прочитал ваш код и выяснил ваш сценарий написания этого кода,
в вашем коде есть серьезные проблемы:
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) попадают в бесконечный цикл.
В вашем конструкторе у вас есть:
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);