There are two C++ projects - an automated trading solution, and a unit/regression test application - sharing the same custom C++ library, using the Qt framework. The applications were previously working and now they are not.
Neither project's source, nor the source of the library, had been changed prior to the problem occurring. The apparent problem on either application is not the same as the other application, but it would appear the root cause is the same.
Prior to the problem(s) appearing I installed cygwin with the default installation except for adding g++, cleaned the solution and re-built, so I believe the cygwin install to be the likely culprit. There are no apparent changes to the PATH variables. I have since uninstalled cygwin, but the problem(s) persist.
When running the test project I receive a 'read access violation'. Please see the following code from the unit/regression test project:
void TradeToolsTest::initTestCase(void)
{
QSharedPointer<UnderlyingAsset> spy = TradeToolsTest::parentLists->getUnderlyingAsset("SPY");
QSharedPointer<QMap<qint64, QSharedPointer<Bar>>> bar30 = QSharedPointer<QMap<qint64, QSharedPointer<Bar>>>(new QMap<qint64, QSharedPointer<Bar>>);
// Convert the bars from JSON to a list of Bars
QSharedPointer<QVector<QSharedPointer<Bar>>> tempBar = api->jsonArrayToItemArray<Bar>(this->mockData["bars"]["spy"]["minute"]["30"].array(), (processJSONObject)TradeTools::Financial::jsonToBar, TradeToolsTest::parentLists);
// Insert the bars into the expected container type
for(QVector<QSharedPointer<Bar>>::iterator itBar=tempBar->begin(), endBar=tempBar->end(); itBar!=endBar; itBar++)
bar30->insert((*itBar)->timestamp, *itBar);
// Add the bars to the asset
spy->addBars(timeframe30, bar30, TradeToolsTest::state, adequateBarCount, TradeToolsTest::parentLists, TradeToolsTest::internalComm, TradeToolsTest::barAdded);
}
bool OQIAsset::addBars(const BarTime barTime, const QSharedPointer<QMap<qint64, QSharedPointer<Bar>>> bar, const QSharedPointer<AppState> appState, bool &adequateBarCount, const QSharedPointer<ParentLists> parentLists, const QSharedPointer<InternalCommunication> internalComm, const BarAdded realBarAdded)
{
return TradeTools::Financial::addBars<OQIAsset>(this, barTime, bar, this->strikeIncrement, appState, adequateBarCount, parentLists, internalComm, realBarAdded);
}
Note: class 'UnderlyingAsset' is derived from class 'OQIAsset'.
The above is a minimal version of the code to explain the problem.
Should I set a breakpoint on the return statement within function 'OQIAsset::addBars' and add 'bar.value' to the watch window, the QMap::size property has some huge value, instead of the expected value of '200'. When I move backward on the call stack to the calling function 'TradeToolsTest::initTestCase' and add 'bar30.value' to the watch window, the QMap::size property is '200' as expected. The pointer of the shared object is the same address.
The object types are the same, except the type in the callee function is const - removing 'const' results in the same issue - I was doubtful this would fix the problem given there have been no code changes prior to the issue appearing.
The problem on the trading bot application is that the Qt library mistakenly believes QApplication has not been instantiated prior to a QWidget being instantiated. Please see the following code:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Systematic w;
w.show();
return a.exec();
}
Systematic::Systematic(QWidget *parent)
: QMainWindow(parent)
{
Systematic::initUI();
}
void Systematic::initUI(void)
{
Systematic::profitLossChart = new LineChartView;
}
Error: 'QWidget: Must construct a QApplication before a QWidget'.
Visual Studio Version: Community 2022 17.12.3
Qt Version: 6.8.1, using msvc2022_64
OS: Windows 11
I have upgraded Qt from 6.7.2 to 6.8.1, and I have upgraded Visual Studio to the latest version, but the problem(s) still persist.
As mentioned above, I have cleaned and rebuilt the solution (including manually deleting the debug / x64 folders from the project directory.), I have uninstalled cygwin, and I have checked the PATH variables for obvious new entries.
I appreciate any help you are able to provide.
The two applications, as well as the library, were all being compiled as Debug builds.
The issue was due to setting 'Project Properties -> Configuration Properties -> Use Debug Libraries' of the two executable projects being set to 'No', which I found entirely strange that this setting became an issue when it was not before.
I researched further and discovered:
The runtime issue when compiling a Debug version of TradeTools with Use Debug Libraries set to "No" could be caused by a mismatch between the build configuration and the libraries being linked or used. Here’s why this matters and how it could affect the applications:
Mismatch Between CRT Libraries
Debug builds typically link against debug versions of the C runtime (CRT), like MSVCRTD.lib, while Release builds link against MSVCRT.lib. If Use Debug Libraries is set to "No", the compiler links against the Release CRT, but the code and dependencies (like TradeTools) may still be expecting debug symbols and debug-specific memory management behavior.
Memory Allocation Differences
Debug and Release CRTs manage memory differently (e.g., debug CRT adds padding and performs extra checks). If the TradeTools library is compiled with Debug settings but linked against Release CRT, any cross-boundary allocation/deallocation (e.g., new in DLL, delete in EXE) could lead to heap corruption or invalid pointer exceptions.
Symbol Mismatch
Debug builds often include extra symbols for debugging (like assert, extra std::vector checks, etc.). If you're running a debug build but linking to the Release CRT, you may encounter "Entry Point Not Found" or unresolved symbol issues because the debug symbols aren’t present in the linked Release CRT.
Thank you to those that commented / helped.