Qt 6.6.0 Destructor of QList causes a crash.
-
I was writing some code to explore using theQTreeWidget class and I'm getting a crash in the destructor of a QList:
I'm using Qt version 6.6.0 with MSVC 2019, building for Debug x64:
It's a similar issue as posted in here: https://forum.qt.io/topic/151502/my-qt-6-6-0-code-crashs-in-debug-mode-qarraydatapointer-and-not-on-release-on-windows
This is my entire program
QApplication app(argc, argv); QTreeWidget* treeWidget = new QTreeWidget(); treeWidget->setColumnCount(1); QList<QTreeWidgetItem*> items; for (int i = 0; i < 10; ++i) { items.append(new QTreeWidgetItem(treeWidget, QStringList(QString("item: %1").arg(1)))); } treeWidget->insertTopLevelItems(0, items); treeWidget->show(); return app.exec();
The issue happens right after
items.append(new QTreeWidgetItem(treeWidget, QStringList(QString("item: %1").arg(1))));
If I modify my program and move the QStringList into a local variable called 'qstlist' declared within the main function's scope, the program runs just fine. But of course as soon as I exit the GUI and the exec function finishes, the destructor still gets called to clean up the local variable and I do still get the same error, but at least I get to see the GUI before that point.
int main(int argc, char *argv[]) { QApplication app(argc, argv); QTreeWidget* treeWidget = new QTreeWidget(); treeWidget->setColumnCount(1); QList<QTreeWidgetItem*> items; QStringList qstlist = QStringList(QString("item: %1").arg(1)); for (int i = 0; i < 10; ++i) { items.append(new QTreeWidgetItem(treeWidget, qstlist)); } treeWidget->insertTopLevelItems(0, items); treeWidget->show(); return app.exec(); }
-
Of course, I clasically forgot to mention the most important detail:
If I continue through the breakpoint this is the specific error that I receive from windows:
Seems to me that for some reason the destructor of the QStringList is trying to deallocate memory that isn't pointing to an actual block on the Heap. Any ideas?
-
Of course, I clasically forgot to mention the most important detail:
If I continue through the breakpoint this is the specific error that I receive from windows:
Seems to me that for some reason the destructor of the QStringList is trying to deallocate memory that isn't pointing to an actual block on the Heap. Any ideas?
@human99 From my Pic you are mixing debug and release libs somewhere. Please show me your CMakeLists.txt
-
@human99 From my Pic you are mixing debug and release libs somewhere. Please show me your CMakeLists.txt
This is the CMakeLists.txt, I just took it from the calculator example from the examples folder within QtBase. I copy pasted the whole calculator example to a different folder and built from there.
I'm not actually using the calculator code at all though. I cut all the code out to just test out the QTreeWidget class. I could only keep main.cpp and the app would work the same.
# Copyright (C) 2022 The Qt Company Ltd. # SPDX-License-Identifier: BSD-3-Clause cmake_minimum_required(VERSION 3.16) project(calculator LANGUAGES CXX) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/widgets/calculator") find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets) qt_standard_project_setup() qt_add_executable(calculator button.cpp button.h calculator.cpp calculator.h my_tree.cpp my_tree.h main.cpp ) set_target_properties(calculator PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE ) target_link_libraries(calculator PRIVATE Qt6::Core Qt6::Gui Qt6::Widgets ) install(TARGETS calculator RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" )
-
@Christian-Ehrlicher What do you mean mixing debug and release libs? As in, I'm linking with Qt libs compiled for debug/release at the same time?
If that's the case I've only ever compiled Qt6 once for Release x64.
-
@Christian-Ehrlicher What do you mean mixing debug and release libs? As in, I'm linking with Qt libs compiled for debug/release at the same time?
If that's the case I've only ever compiled Qt6 once for Release x64.
@human99 said in Qt 6.6.0 Destructor of QList causes a crash.:
If that's the case I've only ever compiled Qt6 once for Release x64.
Then you must not build your own application for Debug, as you say you have. Everything --- your application and any libraries it uses, including Qt --- must all be compiled for only one of Debug or Release. You would need to compile your Qt6 for Debug if you want to do the same for your program
I believe MSVC/Windows runtime C++ libraries make it so it is possible to mix these during a compilation/link, and if so that causes such problems as you say, weird crashes.
-
@human99 said in Qt 6.6.0 Destructor of QList causes a crash.:
If that's the case I've only ever compiled Qt6 once for Release x64.
Then you must not build your own application for Debug, as you say you have. Everything --- your application and any libraries it uses, including Qt --- must all be compiled for only one of Debug or Release. You would need to compile your Qt6 for Debug if you want to do the same for your program
I believe MSVC/Windows runtime C++ libraries make it so it is possible to mix these during a compilation/link, and if so that causes such problems as you say, weird crashes.
-
@human99 said in Qt 6.6.0 Destructor of QList causes a crash.:
If that's the case I've only ever compiled Qt6 once for Release x64.
Then you must not build your own application for Debug, as you say you have. Everything --- your application and any libraries it uses, including Qt --- must all be compiled for only one of Debug or Release. You would need to compile your Qt6 for Debug if you want to do the same for your program
I believe MSVC/Windows runtime C++ libraries make it so it is possible to mix these during a compilation/link, and if so that causes such problems as you say, weird crashes.
-
@JonB
Thank you very much for the answer, I had no idea that was the case.So my by mixing debug and release what is meant is literally don't build your own application in debug with Qt release libs or vice versa.
@human99
Exactly that. I don't quite know how in your situation all the stuff successfully links when some is debug-only and some is release-only, I don't know if that is something MSVC permits, but it doesn't sound good. All of one kind or another, then see if your bug occurs. -
@human99
Exactly that. I don't quite know how in your situation all the stuff successfully links when some is debug-only and some is release-only, I don't know if that is something MSVC permits, but it doesn't sound good. All of one kind or another, then see if your bug occurs.@JonB
Thank you very much for the info. I built the app for release and it works perfectly fine. As you could tell I'm a bit new to system's languages so I never knew about this.May I ask how do you automate this with CMake?
I've compiled QT for x64 Release and installed it in C:\qt6. I imagine if I wanted to build my app for debug I'd need to recompile QT for x64 debug and install it where?
I can install it in some other arbitrary path and figure out how to manually get this working but is there any sensible way to install it such that a CMake flag would automatically build with the appropriate qt version?
-
@JonB
Thank you very much for the info. I built the app for release and it works perfectly fine. As you could tell I'm a bit new to system's languages so I never knew about this.May I ask how do you automate this with CMake?
I've compiled QT for x64 Release and installed it in C:\qt6. I imagine if I wanted to build my app for debug I'd need to recompile QT for x64 debug and install it where?
I can install it in some other arbitrary path and figure out how to manually get this working but is there any sensible way to install it such that a CMake flag would automatically build with the appropriate qt version?
-
@human99
Exactly that. I don't quite know how in your situation all the stuff successfully links when some is debug-only and some is release-only, I don't know if that is something MSVC permits, but it doesn't sound good. All of one kind or another, then see if your bug occurs.@JonB Yeah you're right there's some funky business going on since now that I built the debug version all the .dlls and .libs names end with a d to differenciate them from their release counterparts.
Why my debug build before was linking to release libraries is beyond me. Then again I am calling cmake through visual studio so I can imagine something being caused by that.
-
@JonB
Thank you very much for the info. I built the app for release and it works perfectly fine. As you could tell I'm a bit new to system's languages so I never knew about this.May I ask how do you automate this with CMake?
I've compiled QT for x64 Release and installed it in C:\qt6. I imagine if I wanted to build my app for debug I'd need to recompile QT for x64 debug and install it where?
I can install it in some other arbitrary path and figure out how to manually get this working but is there any sensible way to install it such that a CMake flag would automatically build with the appropriate qt version?
@human99 said in Qt 6.6.0 Destructor of QList causes a crash.:
I'd need to recompile QT for x64 debug and install it where?
In the same place.
-
@human99 said in Qt 6.6.0 Destructor of QList causes a crash.:
I'd need to recompile QT for x64 debug and install it where?
In the same place.
@Christian-Ehrlicher
I'm compiling on windows so do you mean that when I use configure.bat I provide the same folder as an argument to the
-prefix flag. And build twice, once for debug, once for release and install them to the same directory?I've also seen the -debug-and-release option for configure.bat which seems like it was made for this but unfortunately I'm getting an error when using that flag.
-
@Christian-Ehrlicher
I'm compiling on windows so do you mean that when I use configure.bat I provide the same folder as an argument to the
-prefix flag. And build twice, once for debug, once for release and install them to the same directory?I've also seen the -debug-and-release option for configure.bat which seems like it was made for this but unfortunately I'm getting an error when using that flag.
@human99 said in Qt 6.6.0 Destructor of QList causes a crash.:
And build twice, once for debug, once for release and install them to the same directory?
In the same place.
What else should this mean?
-
@human99 said in Qt 6.6.0 Destructor of QList causes a crash.:
And build twice, once for debug, once for release and install them to the same directory?
In the same place.
What else should this mean?
From the point of view of a beginner that's not familiar with building code it's unintuitive. I assumed the install directory would need to be empty. Thank you very much for the input, both of you solved my problem.
-
-
From the point of view of a beginner that's not familiar with building code it's unintuitive. I assumed the install directory would need to be empty. Thank you very much for the input, both of you solved my problem.
@human99 When you follow https://doc.qt.io/qt-6/windows-building.html then debug and release is built in one step. When you followed it and did only get the release libs then it's a bug on Qt side. Otherwise you did something different without known what to do.
-
@human99 When you follow https://doc.qt.io/qt-6/windows-building.html then debug and release is built in one step. When you followed it and did only get the release libs then it's a bug on Qt side. Otherwise you did something different without known what to do.
@Christian-Ehrlicher Thanks for the extra info. I followed https://wiki.qt.io/Building_Qt_6_from_Git, and looking at the link you provided, it outlines the same steps. The only difference being that the link I followed also shows how to get the sources from the qt git repo.
I don't know if it's a bug on QT's side, I suppose it would be if the build's default behaviour should be to build both debug and release libraries.
To be specific: After I ran configure.bat, the batch script's output to the commandline outlines your build options:
Build options: Mode ................................... release ...
And in my case the mode was set to release. And as a sanity check looking in the install folder, the names of all of the .dlls and .lib files do not end with d, so they're definitely the release binary files.
There is a flag you could pass to configure.bat called -debug-and-release that changes this behaviour. Results in a build error for me, but that's another topic. Building twice, once with -release, and once with -debug separately work flawlessly however.
I used configure.bat as shown in the links, I didn't manually change the target output of the build.
-
@Christian-Ehrlicher Thanks for the extra info. I followed https://wiki.qt.io/Building_Qt_6_from_Git, and looking at the link you provided, it outlines the same steps. The only difference being that the link I followed also shows how to get the sources from the qt git repo.
I don't know if it's a bug on QT's side, I suppose it would be if the build's default behaviour should be to build both debug and release libraries.
To be specific: After I ran configure.bat, the batch script's output to the commandline outlines your build options:
Build options: Mode ................................... release ...
And in my case the mode was set to release. And as a sanity check looking in the install folder, the names of all of the .dlls and .lib files do not end with d, so they're definitely the release binary files.
There is a flag you could pass to configure.bat called -debug-and-release that changes this behaviour. Results in a build error for me, but that's another topic. Building twice, once with -release, and once with -debug separately work flawlessly however.
I used configure.bat as shown in the links, I didn't manually change the target output of the build.
@human99 Ok, thx for the investigation. I'll take a look on it - it should default to debug-and-release to avoid the problems you've encountered.