Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [solved] QHash's insert() wrong use? --> VS-Debugger showed botch data due to missing Qt-Addon for VS
QtWS25 Last Chance

[solved] QHash's insert() wrong use? --> VS-Debugger showed botch data due to missing Qt-Addon for VS

Scheduled Pinned Locked Moved General and Desktop
45 Posts 7 Posters 18.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    huckfinn
    wrote on last edited by
    #1

    Hello peoplez,

    I have a beginner problem with my QHash @QHash<pi_int32, SpecialObject> myQHash;@

    I built a controller, which handles my QHash. This Controller has got a method:
    @void DataController::addNewData(qint32 tID, QString tName, qint32 tCat, qint32 tCon)
    {
    SpecialObject tPI (tID, tName, tCat, tCon); // tPI is set correctly
    this->myQHash.insert(tID, tPI); // wrong values inserted into myQHash
    }
    @

    The object tPI is correctly; all its attributes are correctly set.

    The error is in the next line, where the key-SpecialObject-value pair (tID, tPI) should be inserted to myQHash. It is not real error, but rather an incorrect insertion.

    For testing purposes, I have elsewhere:
    @pDataController.addNewData(2511, tr("Home"), 20481, 1272923);@

    But according to my debugger following values are stored
    (1, BadPtr, 262148, 17) instead of
    (2511, tr("Home"), 20481, 1272923)

    Does anybody know which mistake I have done? I am thankful for any advise.

    Cheers Huck

    1 Reply Last reply
    0
    • H Offline
      H Offline
      huckfinn
      wrote on last edited by
      #2

      !http://img232.imageshack.us/img232/154/forum120.jpg(Here is an screenshot of that debugger output.)!

      As I said, Its no real error, the application does not terminate or interrupt.

      1 Reply Last reply
      0
      • T Offline
        T Offline
        tobias.hunger
        wrote on last edited by
        #3

        SpecialObject goes out of scope right after you insert it into your hash. Afterwards its contents is undefined.

        1 Reply Last reply
        0
        • H Offline
          H Offline
          HuXiKa
          wrote on last edited by
          #4

          You have to create your SpecialObject on the heap, because this way it gets deleted after you leave the addNewData function.

          @

          QHash<pi_int32, SpecialObject*> myQHash;
          @

          @
          void DataController::addNewData(qint32 tID, QString tName, qint32 tCat, qint32 tCon)
          {
          SpecialObject *tPI = new SpecialObject(tID, tName, tCat, tCon);
          this->myQHash.insert(tID, tPI);
          }
          @

          If you can find faults of spelling in the text above, you can keep them.

          1 Reply Last reply
          0
          • H Offline
            H Offline
            huckfinn
            wrote on last edited by
            #5

            Ok, and as far as I know every with new created pointer should be deleted by programmer later on.

            @
            void DataController::addNewData(qint32 tID, QString tName, qint32 tCat, qint32 tCon) {
            SpecialObject *tPI = new SpecialObject(tID, tName, tCat, tCon);
            this->myQHash.insert(tID, tPI);
            delete tPI;
            }
            @

            does not make any sence right? Shall I delete all those SpecialObjects pointers in the destructor later? How would you handle that?

            1 Reply Last reply
            0
            • L Offline
              L Offline
              ludde
              wrote on last edited by
              #6

              A bit difficult to give advice with so little information. If SpecialObject is a small class, and it makes sense to pass SpecialObject objects around by value, then the code you have written should be OK. If not, then you must create the objects on the heap, using new, and then delete them when you no longer need them, e.g. when/before the QHash is destroyed.

              1 Reply Last reply
              0
              • Z Offline
                Z Offline
                ZapB
                wrote on last edited by
                #7

                Looks to me like you have not properly implemented the assignment and/or copy constructor of your SpecialObject class properly.

                @Hunger I thought QHash took a copy of objects when you insert them rather than using a reference to them as you are implying?

                Nokia Certified Qt Specialist
                Interested in hearing about Qt related work

                1 Reply Last reply
                0
                • H Offline
                  H Offline
                  huckfinn
                  wrote on last edited by
                  #8

                  @ludde: Yes at that moment SpecialObject has got one QString and 5 qint32 attributes.
                  However, this is going to be developed and thus rising.

                  @ZapB: Thatswhy I wrote an own class for it, I know that I need special format for output purposes late on. And thatswhy I haven't take "struct".

                  Anyway, creating my object on the heap does not solve my problem either. During debugging I can see botch values in pDataController as on the screenshot above. And same CXX0030 error.

                  1 Reply Last reply
                  0
                  • G Offline
                    G Offline
                    goetz
                    wrote on last edited by
                    #9

                    [quote author="ZapB" date="1309781440"]Looks to me like you have not properly implemented the assignment and/or copy constructor of your SpecialObject class properly.

                    @Hunger I thought QHash took a copy of objects when you insert them rather than using a reference to them as you are implying?[/quote]

                    Correct!

                    bq. To quote from the "docs about container classes":http://doc.qt.nokia.com/4.7/containers.html
                    The values stored in the various containers can be of any assignable data type. To qualify, a type must provide a default constructor, a copy constructor, and an assignment operator. This covers most data types you are likely to want to store in a container, including basic types such as int and double, pointer types, and Qt data types such as QString, QDate, and QTime, but it doesn't cover QObject or any QObject subclass (QWidget, QDialog, QTimer, etc.). If you attempt to instantiate a QList<QWidget>, the compiler will complain that QWidget's copy constructor and assignment operators are disabled. If you want to store these kinds of objects in a container, store them as pointers, for example as QList<QWidget *>.

                    And more important:

                    bq. If we don't provide a copy constructor or an assignment operator, C++ provides a default implementation that performs a member-by-member copy.

                    Theses autogenerated operators and constructors are most likely not sufficient!

                    http://www.catb.org/~esr/faqs/smart-questions.html

                    1 Reply Last reply
                    0
                    • Z Offline
                      Z Offline
                      ZapB
                      wrote on last edited by
                      #10

                      Have you unit tested you SpecialObject class to ensure that it works properly for common operations (e.g. creation, destruction, assignment, copying, output)?

                      Can you post the code for SpecialObject please?

                      Nokia Certified Qt Specialist
                      Interested in hearing about Qt related work

                      1 Reply Last reply
                      0
                      • L Offline
                        L Offline
                        ludde
                        wrote on last edited by
                        #11

                        I think you will have to show us the SpecialObject class, if you cannot figure out what's wrong with it from the help you've been given so far.

                        1 Reply Last reply
                        0
                        • G Offline
                          G Offline
                          goetz
                          wrote on last edited by
                          #12

                          Even better, create a complete test case, consisting of just the class, a main method and a method that triggers the crash.

                          http://www.catb.org/~esr/faqs/smart-questions.html

                          1 Reply Last reply
                          0
                          • H Offline
                            H Offline
                            huckfinn
                            wrote on last edited by
                            #13

                            Here you have compileable but not yet linkable codes. LinkError see bottom.

                            DataItem.cpp
                            @#include "DataItem.h"
                            #include <QString>
                            DataItem::DataItem()
                            {
                            this->dataID = 0;
                            this->dataCon = 0;
                            this->dataCat = 0;
                            this->dataName = "defName";
                            }

                            DataItem::DataItem(qint32 tId, QString tName, qint32 tCat, qint32 tCon)
                            {
                            this->dataID = tId;
                            this->dataCon = tCon;
                            this->dataCat = tCat;
                            this->dataName = tName;
                            }

                            qint32 DataItem::getID() const { return this->dataID; }

                            QString DataItem::getName() const { return this->dataName; }

                            qint32 DataItem::getCat() const { return this->dataCat; }

                            qint32 DataItem::getCon() const { return this->dataCon; }

                            DataItem::~DataItem(void) {}@

                            DataItem.h
                            @#pragma once

                            #include <QString>

                            class DataItem
                            {
                            public:
                            DataItem();
                            DataItem(qint32 tId, QString tName, qint32 tCat, qint32 tCon);
                            ~DataItem(void);

                            qint32 getID() const;
                            QString getName() const;
                            qint32 getCat() const;
                            qint32 getCon() const;

                            private:
                            qint32 dataID;
                            QString dataName;
                            qint32 dataCat;
                            qint32 dataCon;
                            };@

                            DataController.cpp
                            @#include <QHash>
                            #include "DataController.h"
                            #include "DataItem.h"

                            //DataController::DataController(void)
                            //{
                            //
                            //}

                            //void DataController::addNew(DataItem * tPI) { this->myQHash.insert(tPI->getID(), *tPI); }

                            void DataController::addNew(qint32 tID, QString tName, qint32 tCat, qint32 tCon)
                            {
                            //DataItem tPI (tID, tName, tCat, tCon);
                            DataItem * tPI = new DataItem(tID, tName, tCat, tCon);
                            this->myQHash.insert(tID, tPI);
                            }

                            DataController::~DataController(void) {}@

                            DataController.h
                            @
                            #pragma once

                            #include <QString>
                            #include <QHash>
                            #include "DataItem.h"

                            class DataController
                            {
                            public:
                            //DataController(void);
                            ~DataController(void);
                            //void addNew(DataItem * tPI);
                            void addNew(qint32, QString, qint32, qint32);

                            private:
                            QHash<qint32, DataItem*> myQHash;
                            };@

                            MyDockWidget.cpp
                            @#include "MyDockWidget.h"
                            #include "DataController.h"
                            #include <QString>
                            MyDockWidget::MyDockWidget( )
                            {
                            //DataController myDataController;
                            }

                            int MyDockWidget::main(int p_argsc, char *p_argsv[] )
                            {
                            //this->myDataController = new DataController();
                            myDataController.addNew(2511, "Heim", 20481, 1272923);
                            myDataController.addNew(2512, "Work", 20482, 1272963);
                            // Breakpoint here

                            return 1;
                            

                            }
                            @

                            MyDockWidget.h
                            @#ifndef MY_DOCK_WIDGET_H
                            #define My_DOCK_WIDGET_H
                            #include <QString>
                            #include "DataController.h"

                            class MyDockWidget
                            {
                            //Q_OBJECT

                            public:
                                /// @brief constructor
                                MyDockWidget();
                            
                                DataController myDataController;
                            

                            int main( int p_argsc, char *p_argsv[] );
                            };
                            #endif // MY_DOCK_WIDGET_H
                            @

                            I now get a Linker-Error:
                            1>Linking...
                            1>DataItem.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall QString::~QString(void)" (_imp??1QString@@QAE@XZ) referenced in function __unwindfunclet$??0DataItem@@QAE@XZ$0

                            but I did not use any Libs or Dlls??! How is that be?

                            1 Reply Last reply
                            0
                            • Z Offline
                              Z Offline
                              ZapB
                              wrote on last edited by
                              #14

                              Yes you are. You are using the QtCore dll. Also where is your main() function?

                              Nokia Certified Qt Specialist
                              Interested in hearing about Qt related work

                              1 Reply Last reply
                              0
                              • G Offline
                                G Offline
                                giesbert
                                wrote on last edited by
                                #15

                                You are missing the linker options in your pro file.
                                can you show it to us?
                                or what do you use for compiling?

                                For me, your code compiles fine.

                                Nokia Certified Qt Specialist.
                                Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                                1 Reply Last reply
                                0
                                • L Offline
                                  L Offline
                                  ludde
                                  wrote on last edited by
                                  #16

                                  Code looks OK to me. Except your DataController destructor should probably destroy the DataItems. But the way your DataItems are now, you should be able to pass them around by value, i.e. not bother with new/delete and the use of pointers.

                                  1 Reply Last reply
                                  0
                                  • H Offline
                                    H Offline
                                    huckfinn
                                    wrote on last edited by
                                    #17

                                    @Gerolf: Yes the compilation is not my problem ;) My linker will not link my stuff ;)

                                    @ZapB: Ok, I included the %QTDIR%qt4.5.0libQtCore4.lib to
                                    Project --> Properties --> Linker --> General --> Add additional Libraries. But same linker error as above.

                                    bq. 1>Linking...
                                    1>DataItem.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall QString::~QString(void)" (_imp??1QString@@QAE@XZ) referenced in function __unwindfunclet$??0DataItem@@QAE@XZ$0
                                    1>DataController.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall QString::~QString(void)" (_imp??1QString@@QAE@XZ)
                                    ////etc....
                                    1>deldel3 - 19 error(s), 0 warning(s)
                                    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

                                    Qstring is in QtCore as well as far as I know?

                                    The main? Is that wrong?

                                    1 Reply Last reply
                                    0
                                    • H Offline
                                      H Offline
                                      huckfinn
                                      wrote on last edited by
                                      #18

                                      @ludde: Yes of course. I will destroy all DataItems pointers objects which are stored in my heap after all.
                                      But therefore I have to store them first, which was my initial problem. Now, my smaller problem is to make that app run ;)

                                      1 Reply Last reply
                                      0
                                      • Z Offline
                                        Z Offline
                                        ZapB
                                        wrote on last edited by
                                        #19

                                        I could not see a main() function in what you posted.

                                        Nokia Certified Qt Specialist
                                        Interested in hearing about Qt related work

                                        1 Reply Last reply
                                        0
                                        • L Offline
                                          L Offline
                                          ludde
                                          wrote on last edited by
                                          #20

                                          The main function is inside the MyDockWidget class - looks really weird to me... Does the main function not have to be global?

                                          Regarding the link errors, which IDE are you using to build your project?

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved