[Solved]QList adds garbage values even though object to be added has been initialised correctly



  • Hello,

    I am using a QList to add a custom class, called DateList whose definition follows:

    @#include<datelist.h>

    DateList::DateList()
    {
    }

    DateList::DateList(const DateList &other)
    {
    }

    DateList::~DateList()
    {

    }

    DateList::DateList(QDate inputdate, int inputindex,int inputcount)
    {
    this->date=inputdate;
    this->index=inputindex;
    this->count=inputcount;
    }

    QDate DateList::getDate()
    {
    return this->date;
    }

    int DateList::getIndex()
    {
    return this->index;
    }

    int DateList::getCount()
    {
    return this->count;
    }

    void DateList::setDate(QDate inputdate)
    {
    this->date=inputdate;
    }

    void DateList::setIndex(int inputindex)
    {
    this->index=inputindex;
    }

    void DateList::setCount(int inputcount)
    {
    this->count=inputcount;
    }
    @

    Now, in the main method, I want to append objects of type DateList to a QList of DateList(s), i.e. QList<DateList>

    The code defined for this is:

    @#include <QtGui/QApplication>
    #include "mainwindow.h"
    #include<QDir>
    #include<QDateTime>
    #include<datelist.h>
    #include <QImageReader>

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);

    QFile ab22("C:/images/landscape.PNG");
    QFileInfo qi22(ab22);
    QDateTime q22;
    q22=qi22.created();
    QDate date22=q22.date();
    
    DateList dl1;
    QList<DateList> d1;
    
    for(int i=0;i<6;i++)
    {
        dl1.setDate(date22);
        dl1.setIndex(i);
        dl1.setCount(i);
        d1.append(dl1);
    
    }
    

    //remaining code follows
    @

    However, as soon as the append method is called on the QList<DateList>, a DateList object with garbage value is added. The DateList object has the correct values just before the append() is called. Here are two screenshots showing the debug state just before and after the append():

    The first screen is the debugger just halted before the "d1.append()"
    !http://s3.postimage.org/499406667/screen_pre.jpg(debug-pre)!

    Please go to: http://s3.postimage.org/t2io0tp6d/screen_pre.jpg if the image is not embedded above

    The second screen is the debugger after the d1.append() has been called in the first iteration of the for loop and the second iteration is about to begin:
    !http://s4.postimage.org/41xnhb0gv/screen_post.jpg(debug-post)!

    Please go to: http://s4.postimage.org/sv77hyjh1/screen_post.jpg if the image is not embedded above

    Any idea what's going wrong here?

    [EDIT: fixed image links, Volker]



  • You have multiple errors in your class:

    QList, like all other container classes, requires the stored objects to be "assignable":http://doc.qt.nokia.com/4.7/containers.html#assignable-data-type.

    • Your class misses an assignment operator.
    • Your default constructor does not initialize the members to some sane default values.
    • Your copy constructor does nothing (i.e. it does not copy the values!)


  • Thanks a lot Volker! Works like a charm. Just to be sure about what I've written, I'm attaching the revised code below. Please correct me if things are wrong:
    @
    #include<datelist.h>

    DateList::DateList()
    {
    this->count=0;
    this->index=0;
    QDate d(1900,1,1);
    this->date=d;
    }

    DateList::DateList(const DateList &other)
    {
    this->count=other.count;
    this->index=other.index;
    this->date=other.date;
    }

    DateList::~DateList()
    {

    }

    DateList& DateList::operator =(DateList rhs)
    {
    return rhs;
    }

    DateList::DateList(QDate inputdate, int inputindex,int inputcount)
    {
    this->date=inputdate;
    this->index=inputindex;
    this->count=inputcount;
    }

    QDate DateList::getDate()
    {
    return this->date;
    }

    int DateList::getIndex()
    {
    return this->index;
    }

    int DateList::getCount()
    {
    return this->count;
    }

    void DateList::setDate(QDate inputdate)
    {
    this->date=inputdate;
    }

    void DateList::setIndex(int inputindex)
    {
    this->index=inputindex;
    }

    void DateList::setCount(int inputcount)
    {
    this->count=inputcount;
    }
    @



  • Your assignment operator operator= needs a proper implementation (it does not change your data right now and you do not check for self-assignmet!) and it should take a const rhs, so that you can assign a const value to a non-const variable. Have a look at the "C++ FAQ lite/Assignment operators":http://www.parashift.com/c++-faq-lite/assignment-operators.html for some further details.



  • In this specific case, the assignment operator and copy constructor can be left out, because no specific actions are required. This is something the compiler can handle. It is however never a bad thing to have them around (if your class is copyable). Just remember to update them if you add new data fields :P.



  • I am also having a similar problem, but I have no clue how to proceed. Kindly Help.

    savings class
    @#ifndef SAVEITEM_H
    #define SAVEITEM_H
    #include <QtGui>
    #include <QPoint>

    class Savings
    {
    public:

    Savings();
    Savings(int item, QPoint pt);
    Savings& Savings::operator= (Savings const& s);
    Savings(const Savings &other);

    QPoint position;
    int itemtype;
    };

    #endif@

    here are the copy constructor and assignment operator i wrote
    @Savings::Savings(const Savings &other)
    {
    this->position= other.position;
    this->itemtype= other.itemtype;
    }

    Savings& Savings::operator= (Savings const& s)
    {
    if (this != &s)
    {
    //this->position = QPoint(s.position);
    this->position = s.position;
    this->itemtype = s.itemtype;
    }
    return *this;
    } @

    and hence defined a QList
    @QList<Savings> saved;
    Savings anitem = Savings(intToSave, ptToSave);
    saved.append(anitem);@



  • What exactly is the problem you have? and what do your other constructors look like?

    In the Savings class declaration, remove the extra qualifier:
    @Savings& Savings::operator= (Savings const& s);@
    should be
    @Savings& operator= (Savings const& s);@
    gcc would throw an error on that one.



  • I am using visual studio. It is giving no error in compilation.
    Savings& operator = (Savings const &s) throws compilation error.

    During runtime-
    @QList<Savings> saved;
    Savings anitem = Savings(intToSave, ptToSave);
    saved.append(anitem);@
    'anitem' is correctly created, but as soon as line 3 is executed, the object appended in the list 'saved' is garbage.

    other constructors of Savings class-
    @#include "saveitem.h"

    Savings::Savings()
    {
    itemtype = 0;
    position = QPoint(0,0);
    }

    Savings::Savings(int item, QPoint pt)
    {
    itemtype= item;
    position = pt;
    }

    void Savings::setItemType(int item)
    {
    itemtype = item;
    }

    void Savings::setPosition(QPoint pt)
    {
    position = pt;
    }
    int Savings::getItemType() const
    {
    return itemtype;
    }

    QPoint Savings::getPosition() const
    {
    return position ;
    }

    Savings::Savings(const Savings &other)
    {
    this->position= other.position;
    this->itemtype= other.itemtype;
    }

    Savings& Savings::operator= (Savings const& s)
    {
    if (this != &s)
    {
    //this->position = QPoint(s.position);
    this->position = s.position;
    this->itemtype = s.itemtype;
    }
    return *this;
    } @



  • I copied your exact code. Used the following header:
    @#ifndef SAVINGS_H
    #define SAVINGS_H

    #include <QPoint>

    class Savings
    {
    public:
    Savings();
    Savings(int item, QPoint pt);
    Savings(const Savings &other);
    Savings& operator= (Savings const& s);

    void setItemType(int item);
    void setPosition(QPoint pt);
    int getItemType() const;
    QPoint getPosition() const;

    private:
    QPoint position;
    int itemtype;
    };

    #endif // SAVINGS_H
    @

    and main.cpp:
    @#include <QtCore/QCoreApplication>
    #include <QList>
    #include <QDebug>
    #include "savings.h"
    #include <QTimer>

    QDebug &operator << (QDebug &dbg, const Savings &in)
    {
    dbg.nospace() << "<" << in.getItemType() << ", " << in.getPosition() << ">";
    return dbg.space();
    }

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    QList<Savings> s;
    s << Savings(1, QPoint(2,3));
    s << Savings(2, QPoint(1, 0));
    qDebug() << s;

    QTimer::singleShot(5000, &a, SLOT(quit()));
    return a.exec();
    }@

    Nothing wrong with your code, I would say (tested on mingw, but no reason why this shouldn't work on msvc).



  • Thank you Franzk :)
    I'l try it out once more!
    Though i just gave it a shot and changed QList to QVector instead, and it gives the correct output, no clue how!



  • It might just be the fact that you rebuilt a lot of the code after the change. Technically QVector and QList require the same behavior from the stored types.


Log in to reply
 

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