Console application crash on window close



  • I have a console application which works great without QCoreApplication and app.exec(). But as soon as I use them the application would report in the QtCreator "Application output" panel that it has crashed. This is the full source code that is crashing for me:
    FILE: equalizer.h
    @#include "filter.h"
    class equalizer{
    public:
    //equalizer(); // unused ATM
    ~equalizer();

    int addFilter(filter * pF);
    int countFilters(){ return filterList.count(); }
    void bypassFilter(int index, bool bypass=false);
    void lockFilter(int index, bool lock=false);
    bool removeFilter(int index);

    private:
    QList<filter * > filterList;
    };@
    FILE: equalizer.cpp
    @#include "equalizer.h"

    equalizer::~equalizer(){
    qDebug("equalizer::~equalizer()");
    while (!filterList.isEmpty()){
    qDebug("count %d", filterList.count());
    delete filterList.takeLast();
    }
    }

    int equalizer::addFilter(filter * pF){
    qDebug("equalizer::addFilter()");
    if (pF != nullptr){
    filterList.append(pF);
    qDebug("filter added at index %d", filterList.count()-1);
    return filterList.count()-1;
    }

    qWarning("invalid pointer (nullptr)");
    return -1;
    }

    void equalizer::bypassFilter(int index, bool bypass){
    qDebug("equalizer::bypassFilter()");
    if ((index >= 0) && (index <= filterList.count())){
    filterList[index]->bypass = bypass;
    qDebug("bypass set (%d) on filter index %d", bypass, index);
    }
    }

    void equalizer::lockFilter(int index, bool lock){
    qDebug("equalizer::lockFilter()");
    if ((index >= 0) && (index <= filterList.count())){
    filterList[index]->lock = lock;
    qDebug("lock set (%d) on filter index %d", lock, index);
    }
    }

    bool equalizer::removeFilter(int index){
    qDebug("equalizer::removeFilter()");
    if ((index >= 0) && (index <= filterList.count())){
    delete filterList[index];
    filterList[index] = nullptr;
    filterList.removeAt(index);
    qDebug("filter %d removed", index);
    return true;
    }

    qDebug("invalid filter index %d", index);
    return false;
    }@
    FILE: filter.h
    @#include <QtGlobal>
    //#include <QObject>

    #define _FILTER_FC_MIN 20 // Minimum frequency (Hz)
    #define _FILTER_FC_MAX 22000 // Maximum frequency (Hz)
    #define _FILTER_GAIN_MIN -120 // Minimum gain (mdb)
    #define _FILTER_GAIN_MAX +120 // Maximum gain (mdb)

    // Filter types
    enum enFilterType{
    BAND_PASS,
    LOW_PASS,
    HIGH_PASS,
    ALL_PASS,
    NOTCH
    };

    class filter{
    public:
    filter(
    ushort FREQ=_FILTER_FC_MIN, // Hz
    ushort BAND=1000, // Hz
    char GAIN=0, // mdB
    enFilterType TYPE=BAND_PASS,
    bool BYPASS=false,
    bool LOCK=false){
    frequency = FREQ;
    bandwidth = BAND;
    gain = GAIN;
    type = TYPE;
    bypass = BYPASS;
    lock = LOCK;
    }

    /// next parameters might get locked
    ushort bandwidth; // Filter bandwidth (Hz)
    ushort frequency; // Filter frequency (Hz)
    char gain; // Filter gain value (db*10)
    enFilterType type; // The filter type
    /// next parameters will always be unlocked
    bool bypass; // Bypass this filter
    bool lock; // Locks frequency, bandwidth, gain, type
    };@
    FILE: main.cpp
    @#include <QCoreApplication>
    #include "equalizer.h"

    int main(int argc, char *argv[]){
    QCoreApplication app(argc, argv);

    equalizer * eq = new equalizer;
    filter * pFa = new filter;
    filter * pFb = new filter(0); // should generate qWarning: invalid FREQ 0
    filter * pFc = new filter(64, 1000, 127); // should generate qWarning: invalid GAIN 127
    filter * pFd = new filter(250);
    filter * pFe = new filter(4000);

    eq->addFilter(pFa);
    qDebug("filter count: %d", eq->countFilters());
    eq->addFilter(pFb);
    qDebug("filter count: %d", eq->countFilters());
    eq->addFilter(pFc);
    qDebug("filter count: %d", eq->countFilters());
    eq->addFilter(pFd);
    qDebug("filter count: %d", eq->countFilters());
    eq->addFilter(pFe);
    qDebug("filter count: %d", eq->countFilters());
    int ret_code = app.exec();
    pFa = nullptr;
    pFb = nullptr;
    pFc = nullptr;
    pFd = nullptr;
    pFe = nullptr;
    delete eq;
    eq = nullptr;

    return ret_code;
    }@

    The application works just fine until I press the console window' close button. When press it the QtCreator "Application output" panel will report a message like that:
    @C:\Users\T3STY\Documents\Qt\equalizer[64-bit] Qt 5.2.0 ANGLE\release\equalizer.exe crashed@
    The eq destructor is not even being called; if it is you should see some qDebug messages. Strange thing is that Windows is not showing any "application has crashed" popup window, which supposedly means that the crash occurs silently inside app.exec().

    Any idea what's going on ?


  • Lifetime Qt Champion

    Hi,

    Does it also happen if you run it through the debugger ?



  • Oh right, I totally forgot mentioning it.
    The Debugger totally fails. I run through the debugger, the application starts and runs correctly (just like without the debugger), but after I close the application it just says "Debugging has finished". No crash message, no crash Windows popup dialog, nothing shown in the debug window; but the eq object destructor is still not being called which means that somewhere an error occurs. Also, the message "The program has unexpectedly finished." which is usually shown when an application is force closed is not being shown.
    The application crashes whatever Qt version I use (32/64 bit, ANGLE/OpenGL). The project configuration could not be the problem, this is the content:
    @QT += core
    CONFIG += c++11

    HEADERS +=
    equalizer.h
    filter.h

    SOURCES +=
    main.cpp
    equalizer.cpp@

    EDIT
    I tried creating a project from scratch and I have copy-pasted code into new files, the issue persists. I'm thinking about reinstalling my Qt versions binaries, and maybe QtCreator, but I don't have time to do that right now and i'd love not having to do it...


  • Lifetime Qt Champion

    Might be a silly question but… Why don't you delete any of your filters ?



  • Do you mean deleting using equalizer::removeFilter() ?
    If I use removeFilter() it all works great but app.exec() does still send a crash message when it should return. All valid registered (stored in QList) filters should be deleted on exit when the equalizer destructor is called; they should be detached from the QList and deleted (see equalizer::~equalizer() for more details). Unfortunately, during the execution app.exec() creates that crash message and I think the whole application is just force closed, so it never reaches the point of calling the destructor.
    I know at the moment, the code above is not even near something that could be called good code, it has many memory leaks (for example, I didn't delete memory of invalid filters in addFilter() ) but that's a new design that I just started working on since the previous was too much memory hungry.



  • If its in the dtor, then you can add a couple checks and debugging statements to see if your deleting a valid piece of allocated memory.

    Where,
    @
    equalizer::~equalizer(){
    qDebug("equalizer::~equalizer()");
    while (!filterList.isEmpty()){
    qDebug("count %d", filterList.count());
    delete filterList.takeLast();
    }
    }
    @

    Try,
    @
    equalizer::~equalizer(){
    // use foreach when looping / deleting items from a list
    foreach(filter *single, filterList){
    // check if pointer is allocated
    if (filter)
    delete single; // delete memory
    else
    qDebug() << "Filter not allocated..."; // pointer dne

          // remove item from list
          filterList.removeAll(single);
     }
    

    }
    @

    Its possible your filter could be being deleted elsewhere or not allocated correctly if this isn't the complete code.



  • This is the complete source code I'm using, not even a row has been deleted.
    But trust me, the object destructor of the equalizer class is not even being called. The row:
    qDebug("equalizer::~equalizer()");
    wil never output that message in the qDebug panel, and the qDebug message in the while is not showing the message neither.

    Anyway, by using your code I get the same problem, a crashed message, and the equalizer destructor is still not being called.

    At this point I think my Qt binaries might have got corrupted. Can someone try my code above and tell me if it's working for you?



  • If someone could try compiling the code above it would be great. If until tomorrow I won't get any answer from anyone I'll try reinstalling QtCreator and the Qt binaries, but I'd like to avoid that if possible.
    Thanks to anyone.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.