Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Why is my application crashing?



  • So I have been working on a text editor and I came across a problem that I have been trying to figure out. My application crashes every time I click the new file icon or the open file icon.
    My code consists of 3 .cpp files, 2 .hpp files, and 1 .pro file. Plus, a .qrc file for my images
    My main.cpp:

    #include "window.hpp"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
    
        return a.exec();
    }
    

    My window.cpp

    #include "window.hpp"
    #include <string>
    
    const QString appName = "Qute Notepad";
    //others--------------declare
    QString file_dir(QString fullFileName)
    {
        std::string str_v = fullFileName.toStdString();
        size_t findi = str_v.rfind('/');
        QString rtn = rtn.fromStdString(str_v.substr(0, findi-1));
        return rtn;
    }
    QString file_name(QString fullFileName){
        std::string str_v = fullFileName.toStdString();
        size_t findi = str_v.rfind('/');
        QString rtn = rtn.fromStdString(str_v.substr(findi+1));
        return rtn;
    }
    
    //MainWindow---------------------------------------------------------------------------------------------------------------------------
    MainWindow::MainWindow()
    {
        setupMenus();
        setupToolbar();
        setupProgrammingToolbar();
    
        setCentralWidget(fileTabs);
        //setWindowTitle(currentFile); //change to make compatible
        addToolBar(mainToolbar);
        addToolBar(programToolbar);
    
    }
    MainWindow::~MainWindow()
    {
        if(/* DISABLES CODE */ (false)) //change it so it does it every time it's not saved
        {
            QMessageBox notSaved;
            notSaved.setText("Your doument is not saved!");
            notSaved.setInformativeText("Do you wish to save your file?");
            notSaved.setStandardButtons(QMessageBox::Save | QMessageBox::Discard);
            notSaved.setDefaultButton(QMessageBox::Save);
            int ret = notSaved.exec();
    
            if (ret == QMessageBox::Save)
            {
                Save();
            }
    
    
        }
        //delete pointers
        delete newAct;
        delete openAct;
        delete saveAct;
        delete saveAsAct;
        delete undoAct;
        delete redoAct;
        delete copyAct;
        delete cutAct;
        delete pasteAct;
        delete fileTabs;
        delete mainToolbar;
        delete toolNewAct;
        delete toolOpenAct;
        delete toolSaveAct;
        delete programToolbar;
        delete toolCompileAct;
        delete toolRunAct;
    }
    void MainWindow::setupMenus()
    {
        //File Menu> #Tooltips not working, might be the window manager
        newAct->setText("New");
        newAct->setToolTip("Cre<<ates a new file");
        newAct->setShortcut(QKeySequence::New);
        connect(newAct, &QAction::triggered, this, &MainWindow::New);
    
        openAct->setText("Open");
        openAct->setToolTip("Opens a already created file");
        openAct->setShortcut(QKeySequence::Open);
        connect(openAct, &QAction::triggered, this, &MainWindow::Open);
    
        saveAct->setText("Save");
        saveAct->setToolTip("Saves the current open document");
        saveAct->setShortcut(QKeySequence::Save);
        connect(saveAct, &QAction::triggered, this, &MainWindow::Save);
    
        saveAsAct->setText("Save As");
        saveAsAct->setToolTip("Saves the current file to a certain name");
        saveAsAct->setShortcut(QKeySequence::SaveAs);
        connect(saveAsAct, &QAction::triggered, this, &MainWindow::SaveAs);
    
        file = menuBar()->addMenu("&File");
        file->addAction(newAct);
        file->addAction(openAct);
        file->addSeparator();
        file->addAction(saveAct);
        file->addAction(saveAsAct);
    
        //Edit Menu>
    
        undoAct->setText("Undo");
        undoAct->setToolTip("Undos last edit");
        undoAct->setShortcut(QKeySequence::Undo);
        connect(undoAct, &QAction::triggered, this, &MainWindow::Undo);
    
        redoAct->setText("Redo");
        redoAct->setToolTip("Redos last undo");
        redoAct->setShortcut(QKeySequence::Redo);
        connect(redoAct, &QAction::triggered, this, &MainWindow::Redo);
    
        cutAct->setText("Cut");
        cutAct->setToolTip("Cuts the selected text to the clipboard");
        cutAct->setShortcut(QKeySequence::Cut);
        connect(cutAct, &QAction::triggered, this, &MainWindow::Cut);
    
        copyAct->setText("Copy");
        copyAct->setToolTip("Copys the selected text to the clipboard");
        copyAct->setShortcut(QKeySequence::Copy);
        connect(copyAct, &QAction::triggered, this, &MainWindow::Copy);
    
        pasteAct->setText("Paste");
        pasteAct->setToolTip("Pastes the current thing from the clipboard");
        pasteAct->setShortcut(QKeySequence::Paste);
        connect(pasteAct, &QAction::triggered, this, &MainWindow::Paste);
    
        edit = menuBar()->addMenu("&Edit");
        edit->addAction(undoAct);
        edit->addAction(redoAct);
        edit->addSeparator();
        edit->addAction(copyAct);
        edit->addAction(cutAct);
        edit->addAction(pasteAct);
    }
    void MainWindow::setupToolbar()
    {
    
        toolNewAct->setIcon(QIcon(":/new-file.png"));
        connect(toolNewAct, &QAction::triggered, this, &MainWindow::New);
    
        toolOpenAct->setIcon(QIcon(":/open-file.png"));
        connect(toolOpenAct, &QAction::triggered, this, &MainWindow::Open);
    
        toolSaveAct->setIcon(QIcon(":/save-file.png"));
        connect(toolSaveAct, &QAction::triggered, this, &MainWindow::Save);
    
        mainToolbar->addAction(toolNewAct);
        mainToolbar->addAction(toolOpenAct);
        mainToolbar->addAction(toolSaveAct);
    }
    void MainWindow::setupProgrammingToolbar()
    {
        toolCompileAct->setText("Compile");
        connect(toolCompileAct, &QAction::triggered, this, &MainWindow::Compile);
    
        toolRunAct->setText("Run");
        connect(toolRunAct, &QAction::triggered, this, &MainWindow::Run);
    
        programToolbar->addAction(toolCompileAct);
        programToolbar->addAction(toolRunAct);
    }
    
    //Slots--------------------------------------------------------------------------------------------------------------------------------
    void MainWindow::New()
    {
        fileTabs->addFileTab("untitled");
        //fileTabs->refreshTabBar();
        fileTabs->setCurrentWidget(fileTabs->tabList().last().page());
    }
    void MainWindow::Open()
    {
        QString openFileName = QFileDialog::getOpenFileName(this, "NotepadCute: Select a file to open it");
        QFile file_v(file_name(openFileName)+" @" + file_dir(openFileName)+"-NotepadCute"); //ex: my.cpp @~/Documents/My-Qt/-NotepadCute
        fileTabs->addFileTab(file_name(openFileName));
        //fileTabs->refreshTabBar();
        fileTabs->setCurrentWidget(fileTabs->tabList().last().page());
        if(!file_v.open(QIODevice::ReadOnly | QFile::Text)){
            QMessageBox::warning(this, "NotepadCute:Warning", "File could not be opened: " + file_v.errorString());
            return;
        }
        setWindowTitle(openFileName);
        QTextStream inputStream(&file_v);
        QString fileText = inputStream.readAll();
        fileTabs->tabList()[fileTabs->currentIndex()].page()->setText(fileText);
        
    }
    void MainWindow::Save()
    {
        
    }
    void MainWindow::SaveAs()
    {
        
    }
    void MainWindow::Undo()
    {
        
    }
    void MainWindow::Redo()
    {
        
    }
    void MainWindow::Cut()
    {
        
    }
    void MainWindow::Copy()
    {
        
    }
    void MainWindow::Paste()
    {
        
    }
    void MainWindow::TextChanged()
    {
        
    }
    void MainWindow::Run()
    {
        //run (./<file>)
    }
    void MainWindow::Compile()
    {
        //compile (g++)
    }
    
    

    As you could see some of the functions are not finished but that is because I have not gotten around to adding the body.
    My window.hpp

    #include <QtWidgets>
    #include <QtCore>
    #include <QTextCharFormat>
    #include <string>
    #include "filetab.hpp"
    
    
    class MainWindow : public QMainWindow
    {
    public:
        MainWindow();
        ~MainWindow();
    
    private:
    
    
    //Menus>
    
        QMenu *file;
        //>
        QAction *newAct = new QAction;
        QAction *openAct = new QAction;
        QAction *saveAct = new QAction;
        QAction *saveAsAct = new QAction;
        
        QMenu *edit;
        //>
        QAction *undoAct = new QAction;
        QAction *redoAct = new QAction;
        QAction *copyAct = new QAction;
        QAction *cutAct = new QAction;
        QAction *pasteAct = new QAction;
    
        void setupMenus();
    
    //TextEdit>
    /*
        QTextEdit *textEdit = new QTextEdit("");
        QString currentFile = "";
        QTextCharFormat *textFormat;
        bool saved = false;
        void setupTextEdit();
    */
        FileTabs *fileTabs = new FileTabs;
    //Toolbar>
    
        QToolBar *mainToolbar = new QToolBar;
        //>
        QAction *toolNewAct = new QAction;
        QAction *toolOpenAct = new QAction;
        QAction *toolSaveAct = new QAction;
        void setupToolbar();
    
        //--------------------------------------
        QToolBar *programToolbar = new QToolBar;
        //>
        QAction *toolRunAct = new QAction;
        QAction *toolCompileAct = new QAction;
    
        void setupProgrammingToolbar();
    
    
    
    
    
    
    private slots:
        void New();
        void Open();
        void Save();
        void SaveAs();
    
        void Undo();
        void Redo();
    
        void Cut();
        void Copy();
        void Paste();
    
        void TextChanged();
    
        void Run();
        void Compile();
    
    };
    

    My filetab.cpp

    #include "filetab.hpp"
    #include <algorithm>
    //FileTab------------------------------------------------------------------------------------------------------------------------------
    
    FileTab::FileTab(QTextEdit *parent, QString new_file_name) :
         _page(parent),_file_name(new_file_name) 
    {
        
    }
    
    QString FileTab::file_name()
    {
        return _file_name;
    }
    QTextEdit *FileTab::page()
    {
        return _page;
    }
    
    FileTab& FileTab::operator =(FileTab &n)
    {
        _page = n._page;
        _file_name = n._file_name;
        return *this;    
    }
    
    
    
    
    //FileTabs-----------------------------------------------------------------------------------------------------------------------------
    
    FileTabs::FileTabs()
    {
        _tabs.resize(0);
        setTabsClosable(true);
        setMovable(true);
        setUsesScrollButtons(true);
    }
    FileTabs::~FileTabs()
    {}
    FileTab FileTabs::tab(int index)
    {
        return _tabs.at(index);
    }
    void FileTabs::addFileTab(QString n)
    {
        _tabs.push_back(FileTab(new QTextEdit, n));
    }
    void FileTabs::refreshTabBar()
    {
        FileTab* first = _tabs.begin();
        FileTab* last = _tabs.end();
        while(first!=last)
        {
            addTab(first->page(), first->file_name());
            ++first;
        }
        delete first;
        delete last;
    }
    
    void FileTabs::recalibrateVector() //clear of bugs
    {
        FileTab* first = _tabs.begin();
        FileTab* last = _tabs.end();
        int loop = 0;
        while(first!=last)
        {
            if(first->page() != currentWidget()){
                first->_page = dynamic_cast<QTextEdit*>(currentWidget());
            }
            
            ++loop;
            ++first;
        }
        
        delete first;
        delete last;
    }
    

    My filetab.hpp

    
    #include <QtCore>
    #include <QtWidgets>
    
    class FileTabs;
    class MainWindow;
    
    class FileTab{
    public:
        FileTab(QTextEdit *parent = new QTextEdit, QString new_file_name = "");
        QString file_name();
        QTextEdit* page();
        FileTab& operator =(FileTab &n);
    protected:
        
        QTextEdit* _page;
        QString _file_name;
    friend FileTabs;
    };
    
    class FileTabs : public QTabWidget
    {
        Q_OBJECT
    public:
        FileTabs();
        ~FileTabs();
        FileTab tab(int index);
        void addFileTab(QString a);
        void refreshTabBar();
        void recalibrateVector();
        QVector<FileTab> tabList(){return _tabs;}
    protected:
        QVector<FileTab> _tabs;
        FileTab currentFileTab;
        void recalibrate(FileTab n);
    friend MainWindow;
    };
    

    My .pro file

    #-------------------------------------------------
    #
    # Project created by QtCreator 2018-07-14T13:34:42
    #
    #-------------------------------------------------
    
    QT       += core gui widgets
    
    TARGET = NotepadCute
    TEMPLATE = app
    
    # The following define makes your compiler emit warnings if you use
    # any feature of Qt which has been marked as deprecated (the exact warnings
    # depend on your compiler). Please consult the documentation of the
    # deprecated API in order to know how to port your code away from it.
    DEFINES += QT_DEPRECATED_WARNINGS
    
    # You can also make your code fail to compile if you use deprecated APIs.
    # In order to do so, uncomment the following line.
    # You can also select to disable deprecated APIs only up to a certain version of Qt.
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    
    CONFIG += c++11
    
    SOURCES += \
            main.cpp \
            window.cpp \
            filetab.cpp
    
    HEADERS += \
            window.hpp \
            filetab.hpp
    
    FORMS +=
    
    # Default rules for deployment.
    qnx: target.path = /tmp/$${TARGET}/bin
    else: unix:!android: target.path = /opt/$${TARGET}/bin
    !isEmpty(target.path): INSTALLS += target
    
    RESOURCES += \
        toolbaricons.qrc
    
    

    This problem I believe is the FileTabs::refreshTabBar() but I can't figure out the problem

    I am running Qt 5.11.1
    I am running Ubuntu Mate

    Sorry about the weird order of the files the .hpp should come first.
    Thanks in advance!
    alt text


  • Lifetime Qt Champion

    Hi
    Try set break point and see what happens in the function.
    I assume you have dangling pointer or something like that.
    I do wonder why

    void FileTabs::refreshTabBar()
    {
        FileTab* first = _tabs.begin();
        FileTab* last = _tabs.end();
        while(first!=last)
        {
            addTab(first->page(), first->file_name());
            ++first;
        }
        delete first; // is that not an iterator ? 
        delete last;
    }
    
    


  • @Nite-Coder said in Why is my application crashing?:

    void FileTabs::refreshTabBar()
    {
    FileTab* first = _tabs.begin();
    FileTab* last = _tabs.end();
    while(first!=last)
    {
    addTab(first->page(), first->file_name());
    ++first;
    }
    delete first;
    delete last;
    }

    Are you sure you can compile this?

    You are assigning an iterator to pointer?



  • @mrjj I am new to debugging so how would you do that?



  • @koahnig how would you copy an iterator, because I can't directly change the first and last iterator. Should I use std::for_each() ?



  • @Nite-Coder said in Why is my application crashing?:

    @koahnig how would you copy an iterator, because I can't directly change the first and last iterator. Should I use std::for_each() ?

    First of all, does that compile?

    Or do you refer to crashing, but there is compile error?



  • That might work:

    void FileTabs::refreshTabBar()
    {
         for ( QVector<FileTab>::iterator it = _tabs.begin(); it != _tabs.end(); ++it )
        {
             addTab ( it->page(), it->fileName() );
        }
    }
    

    or this too

    void FileTabs::refreshTabBar()
    {
         for ( int i = 0; i < _tabs.size(); ++i  )
        {
             addTab ( _tabs[i].page(), _tabs[i].fileName() );
        }
    }
    

    Note: just typed not tested,but it should compile at least. However, you seem to extend the vector while you want to run a loop over it, if I am not mistaken. Not healthy in any way.

    I am sure there is a for_each possibility, but I am too used to simple for loops.



  • @koahnig It compiles but it crashes the program when I click the new file button and open file button



  • @Nite-Coder said in Why is my application crashing?:

    @koahnig It compiles but it crashes the program when I click the new file button and open file button

    Well, if you say so ...

    I do not see where I should be off the track here.

    1. I cannot just compile your example the resoruce is missing.
    2. I am on windows
    3. I apply std container rules, which are in almost all cases identical to Qt cointainers.

    Anyway before I am on a complete wrong track, I better stop here.


  • Lifetime Qt Champion

    @Nite-Coder
    Hi
    Since we cant run the sample ( as @koahnig tried)
    You should try the debugger
    read/skim this
    http://doc.qt.io/qtcreator/creator-debugging.html
    http://doc.qt.io/qtcreator/creator-debugging-example.html
    make sure start app with F5 (or the other run button)
    and that you are in debug build.

    Then next to the function, left click in side (with lino numbers)
    to get red dot.
    Then press button to run function. it will then stop there.
    Then use F10 to single step line by line and
    see what happens to variable values (in the right side)
    Should give you an idea why it crashes.



  • @koahnig Sorry, I just noticed this. It works now! Thanks! I don't know what I would do without wonderful people like you to help me! alt text


Log in to reply