Weird behavior of QList<T>



  • Hello there!
    I have a slight problem with a QList.
    In the given code, rooms is a QList. Using the "at(i)" method i am trying to get data out of that list.
    But when i am using variables instead of a number as the "i" attribute i am getting an assert error.
    Thanks in advance, Jan

        //doesn't work
        int n = 1;
        printf(building->rooms.at(n).name.toLatin1().data());
        
        //works
        printf(building->rooms.at(1).name.toLatin1().data());
    

  • Moderators

    @advtaco What is the error you get?



  • I am getting a segmentation fault



  • @advtaco said in Weird behavior of QList<T>:

    am getting a segmentation fault

    Could you post stack trace?


  • Moderators

    @advtaco Can you show the real code (I guess you posted just parts or an example)?



  • @jsulm
    This is the function in which it happens, roomCount is 2 in this example, the for-loop works for i = 0 but fails when it increments to i = 1

    void CmdHandler::listRooms()
    {
       int roomCount = building->rooms.count();
       printf("Room listing: \n\r");
       printf(QString(QString::number(building->rooms.count()) + "\r\n").toLatin1().data());
    
       printf("+---------------------------+\n\r");
       for (int i = 0; i < roomCount; i++)
       {
           printf(QString::number(i).toLatin1().data());
           printf(QString("Room #" + QString::number(i) + ", " + building->rooms.at(i).name + "\n\r").toLatin1().data());
           printf(QString("Switches: " + QString::number(building->rooms.at(i).switches.count()) + "\n\r").toLatin1().data());
           printf(QString("Blinds: " + QString::number(building->rooms.at(i).blinds.count()) + "\n\r").toLatin1().data());
           printf("+---------------------------+\n\r");
       }
    }
    
    

    @VRonin
    This is what i get
    https://pydio.advtaco.de/public/33a27b



  • @advtaco said in Weird behavior of QList<T>:

    This is what i get

    that's the assertion, not the stack trace. start your debugger and see the "stack window"



  • @advtaco

    @advtaco said in Weird behavior of QList<T>:

    This is the function in which it happens, roomCount is 2 in this example, the for-loop works for i = 0 but fails when it increments to i = 1
    void CmdHandler::listRooms()
    {
    int roomCount = building->rooms.count();
    printf("Room listing: \n\r");
    printf(QString(QString::number(building->rooms.count()) + "\r\n").toLatin1().data());

    printf("+---------------------------+\n\r");
    for (int i = 0; i < roomCount; i++)
    {
    printf(QString::number(i).toLatin1().data());
    printf(QString("Room #" + QString::number(i) + ", " + building->rooms.at(i).name + "\n\r").toLatin1().data());
    printf(QString("Switches: " + QString::number(building->rooms.at(i).switches.count()) + "\n\r").toLatin1().data());
    printf(QString("Blinds: " + QString::number(building->rooms.at(i).blinds.count()) + "\n\r").toLatin1().data());
    printf("+---------------------------+\n\r");
    }
    }

    can your share full code in building and room class ?



  • @advtaco said in Weird behavior of QList<T>:

    //doesn't work
    int n = 1;
    printf(building->rooms.at(n).name.toLatin1().data());
    
    //works
    printf(building->rooms.at(1).name.toLatin1().data());
    

    int n = 0;
    printf(building->rooms.at(n).name.toLatin1().data());
    its works
    ?



  • @Taz742

    kbuilding.cpp :

    #include "kbuilding.h"
    
    kBuilding::kBuilding(QString name)
    {
        this->name = name;
    }
    
    void kBuilding::addRoom(kRoom newRoom)
    {
        rooms.append(newRoom);
    }
    
    void kBuilding::removeRoom(int remRoom)
    {
        rooms.removeAt(remRoom);
    }
    
    

    kbuilding.h :

    #ifndef KBUILDING_H
    #define KBUILDING_H
    
    #include <QList>
    #include <QString>
    #include "kroom.h"
    
    class kBuilding
    {
    public:
        kBuilding(QString name);
        QString name;
        QList<kRoom> rooms;
        void addRoom(kRoom newRoom);
        void removeRoom(int remRoom);
    };
    
    #endif // KBUILDING_H
    
    

    kRoom.cpp :

    #include "kroom.h"
    
    kRoom::kRoom(QString name)
    {
        this->name = name;
    }
    
    void kRoom::addSwitch(kSwitch newSwitch)
    {
        switches.append(newSwitch);
    }
    
    void kRoom::removeSwitch(int remSwitch)
    {
        switches.removeAt(remSwitch);
    }
    
    void kRoom::addBlind(kBlind newBlind)
    {
        blinds.append(newBlind);
    }
    
    void kRoom::removeBlind(int remBlind)
    {
        blinds.removeAt(remBlind);
    }
    
    

    kroom.h :

    #ifndef KROOM_H
    #define KROOM_H
    
    #include <QList>
    #include <QString>
    #include <kswitch.h>
    #include <kblind.h>
    
    class kRoom
    {
    public:
        kRoom(QString name);
        QList<kSwitch> switches;
        QList<kBlind> blinds;
        QString name;
        void addSwitch(kSwitch newSwitch);
        void removeSwitch(int remSwitch);
        void addBlind(kBlind newBlind);
        void removeBlind(int remBlind);
    };
    
    #endif // KROOM_H
    
    

    kswitch.cpp :

    #include "kswitch.h"
    
    kSwitch::kSwitch(bool initialState, QString knx_address)
    {
        this->currentState = initialState;
        this->knx_address = knx_address;
    }
    
    bool kSwitch::changeState()
    {
        bool newState;
        if( currentState == true )
        {
            newState = false;
        }
        else
        {
            newState = true;
        }
    
        // change state via knx
    
        if( 1 /* if changing state succeeds */)
        {
            this->currentState = newState;
            return true;
        }
        return false;
    }
    
    

    kswitch.h :

    #ifndef KSWITCH_H
    #define KSWITCH_H
    
    #include <QString>
    
    class kSwitch
    {
    public:
        kSwitch(bool initialState, QString knx_address);
        QString knx_address;
        bool currentState;
        bool changeState();
    };
    
    #endif // KSWITCH_H
    
    

    kblind.cpp :

    #include "kblind.h"
    
    kBlind::kBlind(float initialHeight, QString knx_address)
    {
        if(!(0 < initialHeight < 1))
        {
            // error;
        }
        else
        {
            this->currentHeight = initialHeight;
        }
        this->knx_address = knx_address;
    }
    
    bool kBlind::changeHeight(float newHeight)
    {
        if(!(0 < newHeight < 1))
        {
            return false;
        }
        else
        {
            // change state via knx
    
            if(1 /* if changing state succeeds */)
            {
                this->currentHeight = newHeight;
                return true;
            }
            return false;
        }
    }
    
    

    kblind.h

    #ifndef KBLIND_H
    #define KBLIND_H
    
    #include <QString>
    
    class kBlind
    {
    public:
        kBlind(float initialHeight, QString knx_address);
        QString knx_address;
        float currentHeight;
        bool changeHeight(float newHeight);
    };
    
    #endif // KBLIND_H
    
    

    @VRonin

    https://pydio.advtaco.de/public/217d9a
    That's the stack trace



  • @advtaco said in Weird behavior of QList<T>:

    That's the stack trace

    Which one is line 55 of cmdhandler.cpp?

    I know this is something unbelievably obvious that I'm missing but I just can't see the bug yet


  • Moderators

    @advtaco Are you sure you really have roomCount entries in the list? You should check that first.



  • @jsulm Yep, i checked that in the debugger

    @VRonin That's this line:

     printf(QString("Room #" + QString::number(i) + ", " + building->rooms.at(i).name + "\n\r").toLatin1().data());
    


  • @VRonin @jsulm

    @advtaco said in Weird behavior of QList<T>:

    #ifndef KROOM_H
    #define KROOM_H

    #include <QList>
    #include <QString>
    #include <kswitch.h>
    #include <kblind.h>

    class kRoom
    {
    public:
    kRoom(QString name);
    QList<kSwitch> switches;
    QList<kBlind> blinds;
    QString name;
    void addSwitch(kSwitch newSwitch);
    void removeSwitch(int remSwitch);
    void addBlind(kBlind newBlind);
    void removeBlind(int remBlind);
    };

    When I used class in other classes I had a problem with the following:
    like this

    > #include <QList>
    > #include <QString>
    > #include <kswitch.h>
    > #include <kblind.h>
    
    class kSwtich;
    class kBlind;
    

    Could this be a problem anyway?


  • Moderators

    @Taz742 Sory, I don't follow: what problem do you mean?


  • Moderators

    @advtaco Not related to your question: may I ask you why you use printf C function? It makes your code more complex as you need to get char* out of QString. Why not use qDebug for debugging or std::cout for regular std out - you're using C++ not C :-)



  • @jsulm undefined refernce (class name).
    @advtaco you are using Qt 5.9 yeap?
    please check other version if you can.



  • I'm speechless... I can only thing of something weird going on in building

    ok, let's try with an alternative.
    replace

    for (int i = 0; i < roomCount; i++)
       {
           printf(QString::number(i).toLatin1().data());
           printf(QString("Room #" + QString::number(i) + ", " + building->rooms.at(i).name + "\n\r").toLatin1().data());
           printf(QString("Switches: " + QString::number(building->rooms.at(i).switches.count()) + "\n\r").toLatin1().data());
           printf(QString("Blinds: " + QString::number(building->rooms.at(i).blinds.count()) + "\n\r").toLatin1().data());
           printf("+---------------------------+\n\r");
       }
    

    with

    foreach(const kRoom& singleRoom, building->rooms){
    qDebug() << singleRoom.name;
    }
    

  • Moderators

    @Taz742 Well, you need to have the class definition somewhere, a forward declaration isn't a definition.



  • @jsulm said in Weird behavior of QList<T>:

    @advtaco Not related to your question: may I ask you why you use printf C function? It makes your code more complex as you need to get char* out of QString. Why not use qDebug for debugging or std::cout for regular std out - you're using C++ not C :-)

    For more infos on this front, see https://stackoverflow.com/questions/3886105/how-to-print-to-console-when-using-qt



  • @VRonin The qDebug-Variant works! Still don't understand why the old version doesn't but at least it does something now!

    @jsulm @VRonin I am looking into other methods to output now

    @Taz742 Yes, I am using Qt 5.9



  • @advtaco
    The problem was qDebug () or foreach (const kRoom & singleRoom, building-> rooms) ?


Log in to reply
 

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