Results 1 to 4 of 4

Thread: Memory management with assignable types and QHash

  1. #1
    Join Date
    Jan 2010
    Posts
    190
    Thanks
    18
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt5 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Memory management with assignable types and QHash

    Hi! I'm having a relevant doubt so I would like someone to clarify it if possible. I am in this situation: I created a structure which should be assignable, so that I can put it into a container. In this specific case I'm interested in QHash. This is an example:

    Qt Code:
    1. struct MyStruct
    2. {
    3. QString aString;
    4. QString anotherString;
    5. QImage anImage;
    6. }
    To copy to clipboard, switch view to plain text mode 

    as far as I can understand this should be assignable already without default contructor, copy constructor or operator= override.
    First question is: if I copy two MyStruct's this way:

    Qt Code:
    1. MyStruct s;
    2. MyStruct p = s;
    To copy to clipboard, switch view to plain text mode 

    Do I use implicit sharing on the two strings and the image? I mean, does the default operator= of the C++ uses operator= on each of the members? So, when one of those is destroyed, the other one remains valid?

    But what happens when I insert MyStruct in a QHash? If I define a QHash like QHash<int, MyStruct>, and I insert MyStruct's inside, do I have that all the members are only shallow copied with copy-on-write?
    And what happens if I clear the QHash? Do I get that all the values (and keys in case) are destroyed (and member's refcount is decreased)?
    And If I placed a pointer to MyStruct (the object is in the heap then)? I read that in that case the memory is not freed and I have to use qDeleteAll, is this correct?
    Thanks for any clarification!

  2. #2
    Join Date
    Oct 2010
    Posts
    55
    Thanks
    1
    Thanked 11 Times in 10 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    9

    Default Re: Memory management with assignable types and QHash

    If you are not sure what's going on, you can always create your own implicitly shared class to use as value in the QHash, and then output some debug info:
    Qt Code:
    1. #include <QtGui/QApplication>
    2. #include <QSharedData>
    3. #include <QHash>
    4. #include <QDebug>
    5.  
    6. class ImplSharedData : public QSharedData
    7. {
    8. public:
    9. ImplSharedData() : QSharedData()
    10. { qDebug() << "+ImplSharedData data created"; }
    11.  
    12. ~ImplSharedData()
    13. { qDebug() << "-ImplSharedData data destroyed"; }
    14.  
    15. ImplSharedData(const ImplSharedData &other) : QSharedData(other)
    16. { qDebug() << "deep copy of impl. shared data"; }
    17.  
    18. // ...
    19. };
    20.  
    21. class ImplSharedClass
    22. {
    23. public:
    24. ImplSharedClass() : d(new ImplSharedData)
    25. { qDebug() << "+ImplSharedClass object created"; }
    26.  
    27. ~ImplSharedClass() { qDebug() << "-ImplSharedClass object destroyed"; }
    28.  
    29. ImplSharedClass(const ImplSharedClass &other) : d(other.d)
    30. { qDebug() << "shallow copy of ImplSharedClass created"; }
    31.  
    32. ImplSharedClass &operator =(const ImplSharedClass &other)
    33. {
    34. if (this != &other) {
    35. d = other.d;
    36. qDebug() << "shallow copy of ImplSharedClass through assignment";
    37. }
    38. return *this;
    39. }
    40.  
    41. inline void modify() { d.detach(); } // non-const function that modifies the data
    42.  
    43. private:
    44. QSharedDataPointer<ImplSharedData> d;
    45. };
    46.  
    47. struct MyStruct
    48. {
    49. ImplSharedClass shared;
    50. };
    To copy to clipboard, switch view to plain text mode 
    then if in main(), you run
    Qt Code:
    1. MyStruct strukt;
    2. MyStruct strukt2 = strukt;
    3.  
    4. QHash<int, MyStruct> hash;
    5.  
    6. hash.insert(1, strukt);
    7. hash.insert(2, strukt2);
    To copy to clipboard, switch view to plain text mode 
    this will generate:

    +ImplSharedData data created
    +ImplSharedClass object created
    shallow copy of ImplSharedClass created
    shallow copy of ImplSharedClass created
    shallow copy of ImplSharedClass created
    -ImplSharedClass object destroyed
    -ImplSharedClass object destroyed
    -ImplSharedClass object destroyed
    -ImplSharedClass object destroyed
    -ImplSharedData data destroyed

    So the ImplSharedData object is destroyed when the hash falls out of scope. Only one ImplSharedData object exists, but four (4) ImplSharedClass objects, all pointing to the same data.

    Btw, MyStruct p = s; will actually invoke the copy-constructor, but if you, on the other hand write:
    Qt Code:
    1. MyStruct p;
    2. p = s;
    To copy to clipboard, switch view to plain text mode 
    the assignment operator will be used.

    If, instead main() reads something like:
    Qt Code:
    1. MyStruct *struktPtr1 = new MyStruct;
    2. MyStruct *struktPtr2 = new MyStruct(*struktPtr1);
    3.  
    4. QHash<int, MyStruct *> hash2;
    5.  
    6. hash2.insert(1, struktPtr1);
    7. hash2.insert(2, struktPtr2);
    To copy to clipboard, switch view to plain text mode 
    you get:

    +ImplSharedData data created
    +ImplSharedClass object created
    shallow copy of ImplSharedClass created

    Here nothing gets destroyed when the hash is going out of scope, so like you said you need to do:
    Qt Code:
    1. MyStruct *struktPtr1 = new MyStruct;
    2. MyStruct *struktPtr2 = new MyStruct(*struktPtr1);
    3.  
    4. QHash<int, MyStruct *> hash2;
    5.  
    6. hash2.insert(1, struktPtr1);
    7. hash2.insert(2, struktPtr2);
    8.  
    9. qDeleteAll(hash2);
    To copy to clipboard, switch view to plain text mode 
    This gives:

    +ImplSharedData data created
    +ImplSharedClass object created
    shallow copy of ImplSharedClass created
    -ImplSharedClass object destroyed
    -ImplSharedClass object destroyed
    -ImplSharedData data destroyed

    ...and all is well.

    --

    You can also call the modify() function to see what happens when the data is detached (copy-on-write). For example:
    Qt Code:
    1. struktPtr1->shared.modify();
    To copy to clipboard, switch view to plain text mode 

  3. #3
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Memory management with assignable types and QHash

    Quote Originally Posted by Luc4 View Post
    First question is: if I copy two MyStruct's this way:

    Qt Code:
    1. MyStruct s;
    2. MyStruct p = s;
    To copy to clipboard, switch view to plain text mode 

    Do I use implicit sharing on the two strings and the image?
    Yes. If a class uses implicit sharing there is no way to "turn it off" so it is always used.

    I mean, does the default operator= of the C++ uses operator= on each of the members?
    If using operator= can't be avoided (i.e. copy constructor can't be used) then yes.
    So, when one of those is destroyed, the other one remains valid?
    Yes.

    But what happens when I insert MyStruct in a QHash?
    The same rules apply.

    If I define a QHash like QHash<int, MyStruct>, and I insert MyStruct's inside, do I have that all the members are only shallow copied with copy-on-write?
    Yes.

    And what happens if I clear the QHash? Do I get that all the values (and keys in case) are destroyed (and member's refcount is decreased)?
    Reference count of all the data referenced by the hash is decreased by 1 and if it reaches 0, the data is destroyed.

    And If I placed a pointer to MyStruct (the object is in the heap then)?
    Then only pointers stored would be destroyed, leaving the referenced data intact (and causing a memory leak)
    I read that in that case the memory is not freed and I have to use qDeleteAll, is this correct?
    That's correct.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  4. #4
    Join Date
    Jan 2010
    Posts
    190
    Thanks
    18
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt5 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Memory management with assignable types and QHash

    Both of you were very simple and clear. Thank you very much!

Similar Threads

  1. Memory management in Qt?
    By wookoon in forum Qt Programming
    Replies: 7
    Last Post: 6th November 2010, 19:20
  2. Memory Management Reg
    By BalaQT in forum Newbie
    Replies: 10
    Last Post: 4th February 2010, 13:43
  3. Memory management
    By cyberboy in forum Qt Programming
    Replies: 2
    Last Post: 12th June 2008, 21:48
  4. signals and slots with container types like QHash
    By themolecule in forum Qt Programming
    Replies: 3
    Last Post: 28th August 2007, 09:07
  5. Memory management in QT
    By Gayathri in forum Qt Programming
    Replies: 1
    Last Post: 17th November 2006, 08:21

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.