Getting Debug Heap correction from destructor of QStringList
-
wrote on 14 Jun 2024, 13:05 last edited by
I am seeing the crash when QStringList object goes out of scope.
In my code it is used as
QStringList filesList ;
Then appending data to fileslist object.I am using MSVC 2019 compiled QT 6.6.3 prebuilt libraries and moving my earlier 32 bit (QT5) application to 64 bit application. I am able to link and run the program with QT 6 libraries but when running the application it is getting crashed.
I am getting below call stack of crash.
Also getting the assert as below
As I am directly using the built QT libraries so there is less chance that I mix-up the same. In release mode I am not seeing crash at this particular code but my other code is crashing somewhere else.
If I create a simple c++ console application and create QStringlist then I am not seeing this error. Can someone please guide on what I might be missing which is causing this ? Any help is appreciated.
-
Please provide more context (code can be very helpful).
How is this string list used before it is destructed? -
wrote on 14 Jun 2024, 15:54 last edited by
QStringList filesList ; if (!cb->currentText().isEmpty()) { filesList.append(ConvertFromQtSeparator(cb->currentText())); } else { filesList.append("."); } for (int i = 0, iComboCount = cb->count(); i<iComboCount; ++i) { QString item = ConvertFromQtSeparator(cb->itemText(i)); if (!item.isEmpty() && !filesList.contains(item, Qt::CaseInsensitive)) { filesList.append(item); } } SettingsGroupInit group("FilesOpeningHistory"); group.settings.setValue(prefix + QString("Files"), filesList); if (!cb->currentText().isEmpty()) { QString combCurrentTex = cb->currentText(); group.settings.setValue(prefix + QString("Directory"), ConvertFromQtSeparator(DIRECTORY::directory(combCurrentTex))); }
This is the code.
I have read posts on same topic where it mentioned about chance of mixing of debug release libs. Does any specific settings in Visual studio C++ application I need to do to wok this ?Note :The release configuration passes this code but fails somewhere later.
-
QStringList filesList ; if (!cb->currentText().isEmpty()) { filesList.append(ConvertFromQtSeparator(cb->currentText())); } else { filesList.append("."); } for (int i = 0, iComboCount = cb->count(); i<iComboCount; ++i) { QString item = ConvertFromQtSeparator(cb->itemText(i)); if (!item.isEmpty() && !filesList.contains(item, Qt::CaseInsensitive)) { filesList.append(item); } } SettingsGroupInit group("FilesOpeningHistory"); group.settings.setValue(prefix + QString("Files"), filesList); if (!cb->currentText().isEmpty()) { QString combCurrentTex = cb->currentText(); group.settings.setValue(prefix + QString("Directory"), ConvertFromQtSeparator(DIRECTORY::directory(combCurrentTex))); }
This is the code.
I have read posts on same topic where it mentioned about chance of mixing of debug release libs. Does any specific settings in Visual studio C++ application I need to do to wok this ?Note :The release configuration passes this code but fails somewhere later.
@OnkarP said in Getting Debug Heap correction from destructor of QStringList:
mixing of debug release libs
Yes, this can lead to strange problems on Windows.
Not sure where in Visual Studio you have to check.
But basically you have to check our debug build configuration (which libraries are linked). It also depends on the build system you're using. -
wrote on 18 Jun 2024, 05:29 last edited by
@jsulm : Can you please explain what do you mean by build system ?
I am using the pre built libraries and dlls (QT6.6.3 MSVC 2019_64bit) which are available in QT installer tool. I am referencing the debug libs (having "d" suffixed) for debug configuration. I am using Visual studio 2022.I was successful with building my application(which was 32 bit) with QT5 prebuilt libraries for 32 bit. Same approach I am trying to convert my 32 bit application to 64 bit.
-
Please show your CMakeLists.txt.
-
wrote on 18 Jun 2024, 06:17 last edited by
@Christian-Ehrlicher
Which one you want to look from installed folder ?I have installed from here and not built on my own.
Thanks,
Onkar -
The CMakeLists.txt from your project. Or pro file - depending on how you built your project
-
wrote on 18 Jun 2024, 07:15 last edited by
-
Lifetime Qt Championwrote on 18 Jun 2024, 07:30 last edited by Christian Ehrlicher
So you create the solution manually? Does it crash in the debug version or when you execute it in the Release version?
Minimize your code until it either does no longer crash or is that small that you can post it here (not more than 50 lines should be necessary). -
wrote on 18 Jun 2024, 07:42 last edited by OnkarP
Yes. In Debug version it crashes and in Release it passes that code but again fails somewhere else.
This is code from one of my function. When filesList object goes out of scope then I am getting crash and Debug assertion as mentioned in the post.========================================================================
QStringList filesList ; if (!cb->currentText().isEmpty()) { filesList.append(ConvertFromQtSeparator(cb->currentText())); } else { filesList.append("."); } for (int i = 0, iComboCount = cb->count(); i<iComboCount; ++i) { QString item = ConvertFromQtSeparator(cb->itemText(i)); if (!item.isEmpty() && !filesList.contains(item, Qt::CaseInsensitive)) { filesList.append(item); } } SettingsGroupInit group("FilesOpeningHistory"); group.settings.setValue(prefix + QString("Files"), filesList); if (!cb->currentText().isEmpty()) { QString combCurrentTex = cb->currentText(); group.settings.setValue(prefix + QString("Directory"), ConvertFromQtSeparator(DIRECTORY::directory(combCurrentTex))); }
==================================================================
Additional information is that my application has UI and moc files are generated for them. The setting to create moc file is as below
Thanks for looking into this. Appreciated.
-
Lifetime Qt Championwrote on 18 Jun 2024, 08:00 last edited by Christian Ehrlicher
This is no minimal, compileable example but just some piece of unreadable code... Please at least properly format your code.
-
Yes. In Debug version it crashes and in Release it passes that code but again fails somewhere else.
This is code from one of my function. When filesList object goes out of scope then I am getting crash and Debug assertion as mentioned in the post.========================================================================
QStringList filesList ; if (!cb->currentText().isEmpty()) { filesList.append(ConvertFromQtSeparator(cb->currentText())); } else { filesList.append("."); } for (int i = 0, iComboCount = cb->count(); i<iComboCount; ++i) { QString item = ConvertFromQtSeparator(cb->itemText(i)); if (!item.isEmpty() && !filesList.contains(item, Qt::CaseInsensitive)) { filesList.append(item); } } SettingsGroupInit group("FilesOpeningHistory"); group.settings.setValue(prefix + QString("Files"), filesList); if (!cb->currentText().isEmpty()) { QString combCurrentTex = cb->currentText(); group.settings.setValue(prefix + QString("Directory"), ConvertFromQtSeparator(DIRECTORY::directory(combCurrentTex))); }
==================================================================
Additional information is that my application has UI and moc files are generated for them. The setting to create moc file is as below
Thanks for looking into this. Appreciated.
wrote on 18 Jun 2024, 08:03 last edited by JonB@OnkarP
As @Christian-Ehrlicher has said. And if your problem arises "When filesList object goes out of scope" then you need to provide code where that happens, yours just declaresQStringList filesList ;
somewhere and maybe it goes out of scope somewhere else but we don't know.You need to reduce your issue to a 50-line, standalone, single file, compilable reproducer for people to look at (and maybe you will find the issue yourself if you do so). If your problem is to do with a
QStringList
scope then presumably it does not need any combobox or UI stuff. And if it can "again fails somewhere else." then clearly full context is important.You could also look at/show the stack trace when it crashes from Debug version.
-
wrote on 18 Jun 2024, 08:32 last edited by
Hello, As mentioned in my first post when I tried almost similar code in console application then I am not seeing this error.
====Sample code Starts=================#include <iostream> #include <QtCore/qcoreapplication.h> #include <QtCore/qlist.h> bool DoSomeManipulation() { // Creating a QStringList QStringList fruits; // Adding items to the list fruits << "Apple" << "Banana" << "Cherry" << "Date"; // Accessing elements using index qDebug() << "First fruit:" << fruits.at(0); qDebug() << "Last fruit:" << fruits.last(); // Iterating through the list qDebug() << "\nAll fruits:"; for (const QString& fruit : fruits) { qDebug() << fruit; } // Checking if list contains a specific item QString searchFruit = "Banana"; if (fruits.contains(searchFruit)) { qDebug() << "\nFound" << searchFruit << "in the list."; } else { qDebug() << "\n" << searchFruit << "not found in the list."; } // Sorting the list alphabetically fruits.sort(); qDebug() << "\nSorted fruits:"; for (const QString& fruit : fruits) { qDebug() << fruit; } return true; } int main(int argc, char* argv[]) { QCoreApplication app(argc, argv); bool t = DoSomeManipulation(); return app.exec(); }
===========Sample code ends====================================
My function is exact similar which gets called on some windows button action.
====Sample code starts=========================void COpenDlg::SaveSettingFilesList(QComboBox* cb, QString prefix) { if (cb->count() == 0) { return; } QStringList filesList; if (!cb->currentText().isEmpty()) { filesList.append(ConvertFromQtSeparator(cb->currentText())); } else { filesList.append("."); } for (int i = 0, iComboCount = cb->count(); i < iComboCount; ++i) { QString item = ConvertFromQtSeparator(cb->itemText(i)); if (!item.isEmpty() && !filesList.contains(item, Qt::CaseInsensitive)) { filesList.append(item); } } SettingsGroupInit group("FilesOpeningHistory"); group.settings.setValue(prefix + QString("Files"), filesList); if (!cb->currentText().isEmpty()) { QString combCurrentTex = cb->currentText(); group.settings.setValue(prefix + QString("Directory"), ConvertFromQtSeparator(DIRECTORY::directory(combCurrentTex))); } }
====Sample code ends==========================
While exiting this function I get crash. The call stack looks likeThe assert window
Please let me know if I can add any additional information.
-
Hello, As mentioned in my first post when I tried almost similar code in console application then I am not seeing this error.
====Sample code Starts=================#include <iostream> #include <QtCore/qcoreapplication.h> #include <QtCore/qlist.h> bool DoSomeManipulation() { // Creating a QStringList QStringList fruits; // Adding items to the list fruits << "Apple" << "Banana" << "Cherry" << "Date"; // Accessing elements using index qDebug() << "First fruit:" << fruits.at(0); qDebug() << "Last fruit:" << fruits.last(); // Iterating through the list qDebug() << "\nAll fruits:"; for (const QString& fruit : fruits) { qDebug() << fruit; } // Checking if list contains a specific item QString searchFruit = "Banana"; if (fruits.contains(searchFruit)) { qDebug() << "\nFound" << searchFruit << "in the list."; } else { qDebug() << "\n" << searchFruit << "not found in the list."; } // Sorting the list alphabetically fruits.sort(); qDebug() << "\nSorted fruits:"; for (const QString& fruit : fruits) { qDebug() << fruit; } return true; } int main(int argc, char* argv[]) { QCoreApplication app(argc, argv); bool t = DoSomeManipulation(); return app.exec(); }
===========Sample code ends====================================
My function is exact similar which gets called on some windows button action.
====Sample code starts=========================void COpenDlg::SaveSettingFilesList(QComboBox* cb, QString prefix) { if (cb->count() == 0) { return; } QStringList filesList; if (!cb->currentText().isEmpty()) { filesList.append(ConvertFromQtSeparator(cb->currentText())); } else { filesList.append("."); } for (int i = 0, iComboCount = cb->count(); i < iComboCount; ++i) { QString item = ConvertFromQtSeparator(cb->itemText(i)); if (!item.isEmpty() && !filesList.contains(item, Qt::CaseInsensitive)) { filesList.append(item); } } SettingsGroupInit group("FilesOpeningHistory"); group.settings.setValue(prefix + QString("Files"), filesList); if (!cb->currentText().isEmpty()) { QString combCurrentTex = cb->currentText(); group.settings.setValue(prefix + QString("Directory"), ConvertFromQtSeparator(DIRECTORY::directory(combCurrentTex))); } }
====Sample code ends==========================
While exiting this function I get crash. The call stack looks likeThe assert window
Please let me know if I can add any additional information.
wrote on 18 Jun 2024, 08:48 last edited by JonB@OnkarP
You show a crash on destructing theQStringList filesList
passed to aSettingsGroupInit group
. But you don't show its code so nobody knows what it does with the parameter, which later goes out of scope. Can you not produce a simple, small, complete example exhibiting the crash? -
wrote on 18 Jun 2024, 12:44 last edited by
@JonB : I have spent some time on reproducing this issue outside my application. Here is the code change I done to reproduce the problem. I have called the same function more than once in my sample console application and I am able to reproduce the issue.
// TestQT.cpp : This file contains the 'main' function. Program execution begins and ends there. // #include <iostream> #include <QtCore/qcoreapplication.h> #include <QtCore/qlist.h> bool DoSomeManipulation() { // Creating a QStringList QStringList fruits; // Adding items to the list fruits << "Apple" << "Banana" << "Cherry" << "Date"; // Accessing elements using index qDebug() << "First fruit:" << fruits.at(0); qDebug() << "Last fruit:" << fruits.last(); // Iterating through the list qDebug() << "\nAll fruits:"; for (const QString& fruit : fruits) { qDebug() << fruit; } // Checking if list contains a specific item QString searchFruit = "Banana"; if (fruits.contains(searchFruit)) { qDebug() << "\nFound" << searchFruit << "in the list."; } else { qDebug() << "\n" << searchFruit << "not found in the list."; } // Sorting the list alphabetically fruits.sort(); qDebug() << "\nSorted fruits:"; for (const QString& fruit : fruits) { qDebug() << fruit; } return true; } int main(int argc, char* argv[]) { QCoreApplication app(argc, argv); bool t = DoSomeManipulation(); bool t1 = DoSomeManipulation(); bool t2 = DoSomeManipulation(); return app.exec(); }
Additional include directories
Hope you will also able to see the crash!
-
@JonB : I have spent some time on reproducing this issue outside my application. Here is the code change I done to reproduce the problem. I have called the same function more than once in my sample console application and I am able to reproduce the issue.
// TestQT.cpp : This file contains the 'main' function. Program execution begins and ends there. // #include <iostream> #include <QtCore/qcoreapplication.h> #include <QtCore/qlist.h> bool DoSomeManipulation() { // Creating a QStringList QStringList fruits; // Adding items to the list fruits << "Apple" << "Banana" << "Cherry" << "Date"; // Accessing elements using index qDebug() << "First fruit:" << fruits.at(0); qDebug() << "Last fruit:" << fruits.last(); // Iterating through the list qDebug() << "\nAll fruits:"; for (const QString& fruit : fruits) { qDebug() << fruit; } // Checking if list contains a specific item QString searchFruit = "Banana"; if (fruits.contains(searchFruit)) { qDebug() << "\nFound" << searchFruit << "in the list."; } else { qDebug() << "\n" << searchFruit << "not found in the list."; } // Sorting the list alphabetically fruits.sort(); qDebug() << "\nSorted fruits:"; for (const QString& fruit : fruits) { qDebug() << fruit; } return true; } int main(int argc, char* argv[]) { QCoreApplication app(argc, argv); bool t = DoSomeManipulation(); bool t1 = DoSomeManipulation(); bool t2 = DoSomeManipulation(); return app.exec(); }
My Dependencies
Additional include directories
Crash stack
My QTDIr value
Hope you will also able to see the crash!
wrote on 18 Jun 2024, 13:13 last edited by@OnkarP
Your code looks good. The only thing which alters the list (apart from the initial population) is thefruits.sort()
so I would try commenting that out to see if different behaviour.You might try with code as simple as:
bool DoSomeManipulation() { // Creating a QStringList QStringList fruits; // Adding items to the list fruits << "Apple" << "Banana" << "Cherry" << "Date"; return true; }
You call it 3 times, but do not say if (a) this is required to make it go wrong or (b) which iteration it falls over on.
The "crash site" indicates that the memory allocation area is corrupted, for whatever reason. Make sure you are consistently compiling for 64-bit and the program depends on the MSVC debug runtime (something like
VCRUNTIMED.DLL
orMSVCRTD.DLL
? note the trailingD
), with no sign of a non-debug version.Other than that you will have to await someone with Windows and a similar version of MSVC/Qt to see if happens to them. If you can try a later Qt version than 6.6.3 (e.g. 6.7?) you might test that.
-
wrote on 21 Jun 2024, 05:37 last edited by
Hello,
I investigated further as per your suggestion and have below observations.
In my sample application the current runtime setting isIf I run the code as mentioned above I was getting heap crash. If I add dependency on msvcrtd.lib in my project properties then
the crash is not coming in the same code.Is there anything problem with Qt libraries or these settings are compulsory for Qt6? Because for Qt5 I have not added any such settings when using prebuilt libraries of 32 bit.
Can you please check whether if I am missing anything on this?
In my project if I add dependencies "msvcrtd.lib VCRUNTIMED.lib" then I am able to fix the problem of crashing. But further I am observing specific APIs are not behaving as it was behaving with Qt5.
QtConcurrent::blockingMap(_parts, Movepart(position));
Do you have any suggestions for this ?
Thanks in advance for help!
Regards,
OnkarPS : I have checked with QT 6.7.1 and saw similar issue there.
-
Use a proper build system generator like CMake, qmake or the Qt Visual Studio plugin (which uses CMake) to avoid such problems.
1/23