@AlxMrz

Как устранить ошибку Segmentation fault; core dumped при работе с указателями C++?

Есть 2 класса:
1) UI
//UI.h
#ifndef UI_H
#define UI_H
#include <map>
#include <string>
#include <FL/Fl_Button.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Output.H>
#include <FL/Fl_Widget.H>
using namespace std;

class App;
class Calculator;

class UI {
public:
    Fl_Window *flWindow;
    map< string, Fl_Box* > flBox;
    map< string, Fl_Button*> flButtons;

    Fl_Output *output;
    App *app;
    Calculator *calc;
    
    UI(App* app);
    void startWindow();
    void endWindow();
    void createUI();

    static void resetOutputCb(Fl_Widget *w, void *data);

    void changeOutputValue();
    void prepareOutput(string& insertedValue, bool isNewAction);
};
#endif /* UI_H */

2) Calculator:
//Calculator.h
#ifndef CALCULATOR_H
#define CALCULATOR_H
#include <string>
#include <FL/Fl_Widget.H>
using namespace std;

class UI;

class Calculator {
public:
    Calculator(UI *ui);
    UI *ui;
    
    string leftOperand;
    string action;
    string rightOperand;
    
    static void clickButtonCb(Fl_Widget *w, void *data);
    bool isNewAction(string action);
private:
    void makeCalc(bool isNewValue);
    double plus(double x, double y);
};

#endif /* CALCULATOR_H */


Класс UI инициализирует класс Calсulator и передает ему указатель на самого себя:
UI::UI(App *app) {
    this->app = app;
    this->calc = new Calculator(this);
}


Класс Calculator в свою очередь записывает указатель на UI в одно из своих свойств:
Calculator::Calculator(UI *ui) :
leftOperand("0"),
rightOperand(""),
action("") {
    this->ui = ui;
}
}

Однако теперь при попытке вызвать из Calculator метод класса UI:
void UI::prepareOutput(string& insertedValue, bool isNewAction) {
    if (calc->action != "" && !isNewAction) { // странно, что при calc->action != "" ошибки нет
        if (calc->rightOperand == "0") {
            calc->rightOperand = "";
        }
        calc->rightOperand += insertedValue; // НО ВОТ ТУТ Возникает ошибка при работе с calc->rightOperand
    } else if (!isNewAction) {
        if (calc->leftOperand == "0") {
            calc->leftOperand = "";
        }
        calc->leftOperand += insertedValue;
    }
    if (isNewAction && calc->rightOperand == "" && calc->action != "" && insertedValue != "=") {
        calc->action = insertedValue;
    }
}

возникает ошибка: Segmentation fault; core dumped;
Такая же возникает ошибка, если в классе Calculator сделать что-то вроде :
string str = this->ui->calc->leftOperand; // Segmentation fault; core dumped


При дебаге в переменных видны "странные" для меня значения, ведь ожидаются простые строки:
5b3874af7b5f8755241208.png

Почему возникает эта ошибка и как ее исправить?
  • Вопрос задан
  • 3148 просмотров
Пригласить эксперта
Ответы на вопрос 1
15432
@15432
Системный программист ^_^
Предположу, что у вас в коде что-то типа
UI myUi = UI();
в итоге получается, что создаётся временный объект, пропихивает калькулятору себя, потом просходит копирование этого объекта в конечную переменную (поэлементно, поскольку конструктора копирования нет)
... и временный объект удаляется, при этом в калькуляторе остаётся указатель на временный объект, а не на реальный. Потому и разные указатели в this и calc->ui. Потом происходит обращение в уже освобожденную память, и знакомый вам SegFault (он только по записи возникает, читать освобожденную память дозволяется)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы