Results 1 to 11 of 11

Thread: QHash and pointers - how to clear correctly

  1. #1
    Join Date
    Apr 2008
    Posts
    104
    Thanks
    8
    Thanked 7 Times in 7 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default QHash and pointers - how to clear correctly

    Hello!
    I have the permanent segfault when I try to manually delete pointers from my hash table.
    Here is some code.

    This is the class that I use as hash table value:

    Qt Code:
    1. class CMarkupPair: public QObject
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6.  
    7. QHash <QString, QString> pattern;
    8. };
    To copy to clipboard, switch view to plain text mode 

    And thats my table:

    Qt Code:
    1. QHash <QString, CMarkupPair*> hs_markup;
    To copy to clipboard, switch view to plain text mode 

    I tried many ways to delete values from here. For example:

    Qt Code:
    1. QList<CMarkupPair *> l = hs_markup.values();
    2. foreach (CMarkupPair *p, l)
    3. delete p;
    To copy to clipboard, switch view to plain text mode 

    Or, even worse:

    Qt Code:
    1. QList <QString> hs_markup_keys = hs_markup.keys();
    2.  
    3. foreach (QString key, hs_markup_keys)
    4. {
    5. CMarkupPair *p = hs_markup.take (key);
    6. delete p;
    7. }
    To copy to clipboard, switch view to plain text mode 

    And when I try to "delete p", I have the segfault. My "p" is not NULL, it's ok pointer. Please help

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QHash and pointers - how to clear correctly

    Post the actual output and backtrace of the program when it crashes. Chances are you have a double-free message (i.e. two values in the list point to the same object) but we can only guess. Calling delete on a null pointer is not fatal in C++ but deleting the same object twice is.

  3. #3
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QHash and pointers - how to clear correctly

    Your CMarkupPair class is derived from QObject. When you create the CMarkupPair instances to insert into your hash table, do you give them a non-NULL QObject parent? If you are, then they are probably getting double-deleted - once when you do it, and then again when their parent instance is deleted. Remove your code that deletes the CMarkupPair instances and they will automatically be deleted when their parent instance is deleted.

    You might also try calling p->deleteLater() instead of delete(), but again, deleting them yourself isn't necessary if they have a parent.

  4. #4
    Join Date
    Sep 2009
    Location
    Wroclaw, Poland
    Posts
    1,394
    Thanked 342 Times in 324 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: QHash and pointers - how to clear correctly

    Or just use shared pointers on parent-less objects. Or QPointer<CMarkupPair> - it will be automatically set to 'null' when the object is deleted (by parent or manually). Don't trust raw pointers, each time you declare a raw pointer, a kitten dies.

  5. #5
    Join Date
    Oct 2006
    Location
    New Delhi, India
    Posts
    2,467
    Thanks
    8
    Thanked 334 Times in 317 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QHash and pointers - how to clear correctly

    How about using qDeleteAll (hs_markup);
    hs_markup.clear();


  6. #6
    Join Date
    Apr 2008
    Posts
    104
    Thanks
    8
    Thanked 7 Times in 7 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QHash and pointers - how to clear correctly

    Thanks, deleteLater() resolves the problem! And the CMarkupPair instances have no parent.

    Quote Originally Posted by aamer4yu View Post
    How about using qDeleteAll (hs_markup);
    Segfault

    Thanks to all!
    deleteLater() now is my magic

  7. #7
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QHash and pointers - how to clear correctly

    Don't trust raw pointers, each time you declare a raw pointer, a kitten dies.
    OMG. I now have an army of dead kittens on my conscience. Do they really die, or just lose one of their 9 lives?

  8. #8
    Join Date
    Sep 2009
    Location
    Wroclaw, Poland
    Posts
    1,394
    Thanked 342 Times in 324 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: QHash and pointers - how to clear correctly

    I now have an army of dead kittens on my conscience. Do they really die, or just lose one of their 9 lives?

    OP: I encourage you to get used to smart pointers, you will really appreciate automated memory management. You can use "deleteLater" with shared pointers:
    Qt Code:
    1. static void delete_markup(CMarkupPair* obj){
    2. obj->deleteLater();
    3. }
    4. ...
    5. typedef QSharedPointer<CMarkupPair> CMarkupPairPtr;
    6. QHash <QString, CMarkupPairPtr> hs_markup;
    7. // insert:
    8. hs_markup["key"] = CMarkupPairPtr(new CMarkupPair, delete_markup);
    9. // clear:
    10. hs_markup.clear(); // automatically calls deleteLater() on every object in container
    To copy to clipboard, switch view to plain text mode 

  9. #9
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QHash and pointers - how to clear correctly

    For deleteLater() you can even pass this without the custom deleter helper function

    Qt Code:
    1. QSharedPointer<CMarkupPaor> qobjectPtr(new CMarkupPair, &CMarkupPairt::deleteLater);
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

  10. #10
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QHash and pointers - how to clear correctly

    I'm sort of puzzled why, if the OP created his CMarkupPair instances without parents, simply deleting them would cause a segfault. The only way I could see this happening is if the code as posted for the CMarkupPair class was incomplete, and it also has signals and/or slots that were still connected when the instances were deleted.

    If the instances truly had no other references to them except being in the container (which has no ownership or control of the lifetime of the instances it contains), why would delete() cause a crash? Are there things that happen "behind the curtain" when QObject instances are created which can be undone only during deleteLater()?

  11. #11
    Join Date
    Sep 2009
    Location
    Wroclaw, Poland
    Posts
    1,394
    Thanked 342 Times in 324 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: QHash and pointers - how to clear correctly

    Maybe it was a double-delete kind of issue, and posting two "delete" events for an object solved it - after first one is processed, another one is just removed from the event queue:
    from QObject::~QObject () docs:
    (...) any pending posted events for the object are removed from the event queue.

Similar Threads

  1. Replies: 3
    Last Post: 6th April 2012, 16:44
  2. QHash Clear
    By enricong in forum Qt Programming
    Replies: 6
    Last Post: 12th October 2011, 22:01
  3. QList < QHash < int, QString> > ... clear() is slow
    By JoZCaVaLLo in forum Qt Programming
    Replies: 8
    Last Post: 15th March 2011, 11:07
  4. Does QTableWidget::clear() delete pointers?
    By Slewman in forum Qt Programming
    Replies: 5
    Last Post: 21st January 2011, 16:09
  5. Can QHash::capacity() be smaller than QHash::size()?!?
    By iw2nhl in forum Qt Programming
    Replies: 2
    Last Post: 24th August 2007, 01:17

Tags for this Thread

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.