QTextStream memory leak?



  • Hi all, The program hangs when I execute my code. The issue appears to be in SearchPatrolFile function. the function executes correctly. The while loop executes and finishes, displaying the warning message "Done!" (i use warning messages to debug), but then the program hangs and the rest of the program does not execute. When I remove the while loop everything works fine and the rest of the program executes correctly.

    Not sure where my issue is. Here is the class:

    @#include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "getinfo.h"
    #include "setvariables.h"

    #include <QIODevice>
    #include <QMessageBox>
    #include <QTextStream>

    GetInfo::GetInfo()
    {

    }

    GetInfo::GetInfo(MainWindow *mw)
    {
    QMessageBox::information(mw, mw->mFilename, "GetInfo Class!");

    OpenPatrolFile&#40;mw&#41;;
    
    delete mw;
    mw = NULL;
    

    }

    GetInfo::~GetInfo()
    {

    }

    void GetInfo::OpenPatrolFile(MainWindow *mw) {
    // QFile file("/text.txt"); //If present in Resource
    QFile filePat("E:/Dropbox/SH3 Files/Captains Journal/Captains_Journal/Text Files/Patrols.cfg"); //If present on system

    //Grabbing filename
    QFileInfo fn(filePat);
    patFilename = fn.fileName();
    
    //Grabbing filepath
    QFileInfo fp(filePat);
    patFilepath = fp.filePath();
    
    //Open file for read only. Display error if unsuccessful.
    if(!filePat.open(QIODevice::ReadOnly))
    {
        QMessageBox::warning(mw, "Patrol Log Error", "Patrol Log could not be found not found!");
        return;
    }
    
    
    QTextStream streamPat(&filePat);
    
    SearchPatrolFile&#40;mw, &streamPat&#41;;
    filePat.flush();
    filePat.close();
    

    }

    void GetInfo::SearchPatrolFile(MainWindow *mw, QTextStream *streamPat) {
    SetVariables sv;
    QString linePat;
    QString variable;
    QString patNumS;

    do {
        linePat = streamPat->readLine();
        if (linePat.contains("PatrolNumber=", Qt::CaseSensitive)) {
    
            variable = linePat.section("=",-1);
            int temp = *(sv.SetCurPatrolNum(&variable));
            patNumS = QString::number(temp);
            QMessageBox::information(mw, "Patrol ", "Patrol #" + patNumS);
            QMessageBox::warning(mw, "Found Line", linePat.section("=",-1));
        }
    
    } while(!streamPat->atEnd());
    
    
    
    QMessageBox::information(mw, "Patrol ", "done!!!!!");
    

    }
    @

    Thanks.


  • Moderators

    i'm not sure if this already solves the issue, but you may want to try this (as also stated in the docs):
    @
    QString line;
    do {
    line = stream.readLine();
    } while (!line.isNull());
    @

    Also just for clarification you do not need the "filePat.flush();" since you opened the file in read-only mode.



  • Thanks for the advice, but I tried isNull and its a no go. Any other ideas?


  • Moderators

    what do you mean with "its a no go"?!



  • Hi,
    I don't thing that your textstream or any of that is responsible! That part, apart form what coding standard issues, looks ok and should run without a problem.
    I believe the big problem occur when you try to delete the MainWindow??
    @
    delete mw;
    mw = NULL;
    @
    in the overloaded constructor. Why do you do that??
    Also, maybe for some extra information (if this isn't it). Debug and point to the line where the debug crashes, stops working.
    Greetz



  • How do I debug? There is not debug that comes up it just hangs for about 10 seconds then crashes saying the program has stopped working. But if I remove that while loop all works fine.

    How do I setup my debugger?



  • [quote author="Jeroentje@home" date="1387530804"]Hi,
    I don't thing that your textstream or any of that is responsible! That part, apart form what coding standard issues, looks ok and should run without a problem.
    I believe the big problem occur when you try to delete the MainWindow??
    @
    delete mw;
    mw = NULL;
    @
    in the overloaded constructor. Why do you do that??
    Also, maybe for some extra information (if this isn't it). Debug and point to the line where the debug crashes, stops working.
    Greetz[/quote]

    I tried your suggestion, still the same problem persists.



  • [quote author="Jeroentje@home" date="1387530804"]Hi,
    I don't thing that your textstream or any of that is responsible! That part, apart form what coding standard issues, looks ok and should run without a problem.
    I believe the big problem occur when you try to delete the MainWindow??
    @
    delete mw;
    mw = NULL;
    @
    in the overloaded constructor. Why do you do that??
    Also, maybe for some extra information (if this isn't it). Debug and point to the line where the debug crashes, stops working.
    Greetz[/quote]

    I tried your suggestion, still the same problem persists.



  • hmm, what type of Qt did you install??
    If you installed QtCreator for MinGw you should have a debugger setup and breakpoints may be placed, if you use the VS20xx compiler, you should download and setup the cdb (microsoft console debugger).
    Please, get the debugger working first, then step through your code, if you found the line that causes the crash, let us know.
    Greetz



  • Hi,
    Just to check the rest of your code, but why the use of QFileInfo? The QFile that you use holds the data:
    @
    QString QFile::fileName() const [virtual]
    @
    Also before the while loop should be started, It might be safe to first test if the file even exists:
    @
    bool QFile::exists() const
    @
    Or replace by a while loop instead of a do..while loop. The do..while make the sequence be done (even with a empty file) ones. What happens if the file is empty and your readline will return probably \0 only. Will your qtextstream be beyond the end of the file and thus run forever?
    So, I would write more something like:
    @
    void GetInfo::SearchPatrolFile(MainWindow *mw, QTextStream *streamPat) {
    SetVariables sv;
    QString linePat;
    QString variable;
    QString patNumS;

    while (streamPat.atEnd() == false) // I try to avoid using the ! operator. The reader might get confused to fast if used to much, IYAM
    

    {
    linePat = streamPat->readLine();
    if (linePat.contains("PatrolNumber=", Qt::CaseSensitive)) {

            variable = linePat.section("=",-1);
            int temp = *(sv.SetCurPatrolNum(&variable));
            patNumS = QString::number(temp);
            // Why do you use two dialogs?? What is the use here?
            QMessageBox::information(mw, "Patrol ", "Patrol #" + patNumS);
            QMessageBox::warning(mw, "Found Line", linePat.section("=",-1));
        }
    }  // endof: while (atEnd() == false)
    
    QMessageBox::information(mw, "Patrol ", "done!!!!!");
    

    }
    @



  • [quote author="Jeroentje@home" date="1387543331"]Hi,
    Just to check the rest of your code, but why the use of QFileInfo? The QFile that you use holds the data:
    @
    QString QFile::fileName() const [virtual]
    @
    Also before the while loop should be started, It might be safe to first test if the file even exists:
    @
    bool QFile::exists() const
    @
    Or replace by a while loop instead of a do..while loop. The do..while make the sequence be done (even with a empty file) ones. What happens if the file is empty and your readline will return probably \0 only. Will your qtextstream be beyond the end of the file and thus run forever?
    So, I would write more something like:
    @
    void GetInfo::SearchPatrolFile(MainWindow *mw, QTextStream *streamPat) {
    SetVariables sv;
    QString linePat;
    QString variable;
    QString patNumS;

    while (streamPat.atEnd(&#41; == false) // I try to avoid using the ! operator. The reader might get confused to fast if used to much, IYAM
    

    {
    linePat = streamPat->readLine();
    if (linePat.contains("PatrolNumber=", Qt::CaseSensitive)) {

            variable = linePat.section("=",-1);
            int temp = *(sv.SetCurPatrolNum(&variable));
            patNumS = QString::number(temp);
            // Why do you use two dialogs?? What is the use here?
            QMessageBox::information(mw, "Patrol ", "Patrol #" + patNumS);
            QMessageBox::warning(mw, "Found Line", linePat.section("=",-1));
        }
    }  // endof: while (atEnd() == false)
    
    QMessageBox::information(mw, "Patrol ", "done!!!!!");
    

    }
    @
    [/quote]

    I tried your advice and still no joy.
    When I put atEnd() == true and it skips the while loop, all works fine.

    I'm installing a debugger so I will post results when I get that working.
    Here is my updated code:

    @#include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "getinfo.h"
    #include "setvariables.h"

    #include <QIODevice>
    #include <QMessageBox>
    #include <QTextStream>

    GetInfo::GetInfo()
    {

    }

    GetInfo::GetInfo(MainWindow *mw)
    {
    QMessageBox::information(mw, mw->mFilename, "GetInfo Class!");

    OpenPatrolFile&#40;mw&#41;;
    

    }

    GetInfo::~GetInfo()
    {

    }

    void GetInfo::OpenPatrolFile(MainWindow *mw) {
    // QFile file("/text.txt"); //If present in Resource
    QFile filePat("E:/Dropbox/SH3 Files/Captains Journal/Captains_Journal/Text Files/Patrols.cfg"); //If present on system

    //Open file for read only. Display error if unsuccessful.
    if (!filePat.open(QIODevice::ReadOnly) && filePat.exists())
    {
        QMessageBox::warning(mw, "Patrol Log Error", "Patrol Log could not be found not found!");
        return;
    }
    
    
    QTextStream streamPat(&filePat);
    
    SearchPatrolFile&#40;mw, &streamPat&#41;;
    filePat.flush();
    filePat.close();
    

    }

    void GetInfo::SearchPatrolFile(MainWindow *mw, QTextStream *streamPat) {
    SetVariables sv;
    QString linePat;
    QString variable;
    QString patNumS;

     while(streamPat->atEnd() == false) {
        linePat = streamPat->readLine();
        if (linePat.contains("PatrolNumber=", Qt::CaseSensitive)) {
    
            variable = linePat.section("=",-1);
            int temp = *(sv.SetCurPatrolNum(&variable));
            patNumS = QString::number(temp);
            QMessageBox::information(mw, "Patrol ", "Patrol #" + patNumS);
            QMessageBox::warning(mw, "Found Line", linePat.section("=",-1));
        }
    
    }
    
    
    
    QMessageBox::information(mw, "Patrol ", "done!!!!!");
    

    }@



  • [quote author="Jeroentje@home" date="1387542623"]hmm, what type of Qt did you install??
    If you installed QtCreator for MinGw you should have a debugger setup and breakpoints may be placed, if you use the VS20xx compiler, you should download and setup the cdb (microsoft console debugger).
    Please, get the debugger working first, then step through your code, if you found the line that causes the crash, let us know.
    Greetz[/quote]

    I tried installing this:

    http://www.microsoft.com/en-us/download/confirmation.aspx?id=8279

    it errors while installing. Not sure how else I can get a debugger.



  • Here is the SetVariables class. One of its members is called in the while loop:

    @#include "setvariables.h"
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "getinfo.h"

    #include <QIODevice>
    #include <QMessageBox>

    SetVariables::SetVariables()
    {
    }

    int* SetVariables::SetCurPatrolNum(QString *curPNum) {
    int temp = curPNum->toInt();
    *curPatrolNum = temp + 1;
    return curPatrolNum;
    }
    @



  • Ok, so I found the issue. It was the function I was calling in SetVariables that was causing the issue in the while loop. What did I do wrong? SetCurPatrolNum returns an int pointer. What did I do wrong there?

    So I changed it to return an int non-pointer and all works fine. Again, what was the issue? Was it a memory leak with the pointer? Should I have deleted it in every loop?



  • Ok, so I changed it back to pointer and pointed it to address correctly, in SetVariables class method:

    @int* SetVariables::SetCurPatrolNum(QString *curPNum) {
    int temp = curPNum->toInt();
    temp++;
    curPatrolNum = &temp;
    return curPatrolNum;
    }@

    Now all works well!


  • Lifetime Qt Champion

    Hi,

    Are you aware that you are returning a pointer to a temporary variable ?

    Also why are you returning a pointer to an int that you will deference anyway to get the value of the pointed variable ? Just return the int value.



  • [quote author="SGaist" date="1387579478"]Hi,

    Are you aware that you are returning a pointer to a temporary variable ?

    Also why are you returning a pointer to an int that you will deference anyway to get the value of the pointed variable ? Just return the int value.[/quote]

    Thanks for pointing this out. I am now just returning the value.


Log in to reply
 

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