As you know QMap/QHash are little bit faster than std::map and std::unordered_map … but why? I have no ideas about this before I have used them in high-load muti-thread application. I send data in QHash via queued signal/slot between threads. Anything looks fine, but 1-2 times per day application gets segfault. It was very strange because it crashed after different count iterations but it was millions iterations. GDB shows something like this:
#0 0x00007f8421029107 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 #1 0x00007f842102a4e8 in __GI_abort () at abort.c:89 #2 0x00007f8421067044 in __libc_message (do_abort=do_abort@entry=1, fmt=fmt@entry=0x7f8421159c40 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175 #3 0x00007f842106c81e in malloc_printerr (action=1, str=0x7f8421159d90 "double free or corruption (out)", ptr=<optimized out>) at malloc.c:4996 #4 0x00007f842106d526 in _int_free (av=<optimized out>, p=<optimized out>, have_lock=0) at malloc.c:3840 #5 0x00007f8421ede054 in QHashData::free_helper (this=0x7f8418003a80, node_delete=0x40b324 <QHash<unsigned long, logdata>::deleteNode2(QHashData::Node*)>) at tools/qhash.cpp:496 #6 0x000000000040b364 in QHash<unsigned long, logdata>::freeData (this=0x7f84180bb5e0, x=0x7f8418003a80) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qhash.h:600 #7 0x000000000040f208 in QHash<unsigned long, logdata>::~QHash (this=0x7f84180bb5e0, __in_chrg=<optimized out>) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qhash.h:310
after some days of hard debug, Qt source code reading and liters of green tea i have found that different instances of QHash (and also QMap) may share some data structures. And they may reuse and/or free some internal data structures in different instance of QHash (or QMap). This works perfect in single thread application or if you don’t transfer data between threads but may crash you application in other case.
And there is simple solution issuing a little bit slowdown of inserting/deleting elements in QHash/QMap:
QHash<QString,int> *sharedHash = new QHash<QString,int>; sharedHash->setSharable(false);
And anything goes OK. Or you can use std::unordered_map or std::map :)