QList destructor crashes in release build
-
Here is my sample source code, using Qt 5.4 on Windows:
#include "dialog.h" #include <QAudioDeviceInfo> Dialog::Dialog(QWidget *parent) : QDialog(parent) { qDebug("In constructor"); DoIt(); qDebug("Leaving constructor"); } Dialog::~Dialog() { } void Dialog::DoIt() { qDebug("In DoIt"); QList<QAudioDeviceInfo> micList = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); qDebug("Leaving DoIt"); }
When I build it for Release using MSVC 2010 Express, it crashes after "Leaving DoIt" but before "Leaving Constructor". I assume it is the destructor of the QList that is crashing. It doesn't crash in Debug build, which makes it harder to debug. Anyone have any hints?
Thanks! -
I am curious... You say you are using MSVC2010 express with Qt5.4? Did you rebuild Qt yourself? I'm not sure it matters but I seem to only remember MSVC2013.
Anyway, when I run into stuff like this it is frustrating but you need more info so this means changing things up to try and figure out what is going on.
One thing to note is your code gets this micList but then does nothing with it. So it is obtained then immediately released.
To rule out if the problem is with micList or with the call to availableDevices() I'd leave your code just as it is but not make the call to availableDevices(). Just create a few QAudioDeviceInfo objects of your own and add them to your list. See if it still crashes.
If so, then maybe move your micList definitions to your class as a private item. This way it is not immediately obtained and released.
You might also try to figure out just how big on your system micList is getting so figure out something like sizeof(QAudioDeviceInfo) * micList.Count.
If it is still crashing then I'd switch to trying to allocate the memory for the object yourself like: QList<QAudioDeviceInfo> *micList = new QList<QAudioDeviceInfo>, then fill the list yourself from the return of the availableDevices.
When you run into seemingly strange problems just start moving things around and trying things to see if you can track down what is going on.
Would love to see what you figure out!
-
@SysTech
The reason micList does nothing is this is a tiny project to illustrate a problem I ran into with a bigger application. Per your suggestion, I changed the code as follows and it no longer crashes, so the problem has to do with availableDevices().void Dialog::DoIt() { qDebug("In DoIt"); QAudioDeviceInfo dev1; QAudioDeviceInfo dev2; QList<QAudioDeviceInfo> micList; micList.append(dev1); micList.append(dev2); qDebug("Leaving DoIt"); }
So, now I'll see how I can recode to work around this. Thanks for the help!
-
@MykPel
If I change my DoIt method to be:void Dialog::DoIt() { qDebug("In DoIt"); QAudioDeviceInfo::availableDevices(QAudio::AudioInput); qDebug("Leaving DoIt"); }
it crashes before the "Leaving DoIt" is displayed in the "application output" window. Something seems screwy with QAudioDeviceInfo::availableDevices().
-
@MykPel
This gets stranger all the time. It now crashes when I build it in debug mode. The original program crashes with the following error:
HEAP[TestQList.exe]: Invalid address specified to RtlValidateHeap( 02300000, 0249AE78 )
The stack dump:
0 DbgBreakPoint ntdll 0x7776878e
1 RtlpBreakPointHeap ntdll 0x777d2233
2 RtlpValidateHeapEntry ntdll 0x777a2917
3 RtlValidateHeap ntdll 0x777312c4
4 HeapValidate kernel32 0x7668d610
5 _CrtIsValidHeapPointer dbgheap.c 2036 0x3d75e0
6 _free_dbg_nolock dbgheap.c 1322 0x3d676a
7 _free_dbg dbgheap.c 1265 0x3d6620
8 operator delete dbgdel.cpp 54 0x3d2199
9 QAudioDeviceInfo::`scalar deleting destructor' TestQList 0x3d1691
10 QList<QAudioDeviceInfo>::node_destruct qlist.h 431 0x3d1611
11 QList<QAudioDeviceInfo>::dealloc qlist.h 792 0x3d159b
12 QList<QAudioDeviceInfo>::~QList<QAudioDeviceInfo> qlist.h 767 0x3d1486
13 Dialog::DoIt dialog.cpp 21 0x3d1375
14 Dialog::Dialog dialog.cpp 9 0x3d1271
15 main main.cpp 7 0x3d114c
16 WinMain qtmain_win.cpp 112 0x40a7fd
17 __tmainCRTStartup crt0.c 275 0x3d23c2
18 WinMainCRTStartup crt0.c 189 0x3d226f
19 BaseThreadInitThunk kernel32 0x766cd3c9
20 __RtlUserThreadStart ntdll 0x77761603
21 _RtlUserThreadStart ntdll 0x777615d6Line 21 of dialog.cpp is the exit from the DoIt method.
I'm not sure where to go from here. -
Hi,
Not a really in-depth answer but when I had this kind of problem popping up on Windows, a full rebuild (meaning: nuke the shadow build directories) often fixed it.
-
@SGaist
Are you suggesting rebuilding my app, or rebuilding Qt? What are "shadow build directories"? I deleted the build directories for my app and rebuilt it with the same results. I did not build Qt when I downloaded it; I used the pre-built installer. I see there is now a 5.4.1; I'm using 5.4.0. I'll try updating to the newer one. If that doesn't help, I'll research how to build Qt.