There is an odd dependency in CalcEngine.
CalculatorManager inherits ICalcDisplay and implements a set of virtual calls it exposes, in particular SetPrimaryDisplay.
|
virtual void SetPrimaryDisplay(const std::wstring& pszText, bool isError) = 0; |
When setting a mode in CalculatorManager, e.g.
|
make_unique<CCalcEngine>(true /* Respect Order of Operations */, true /* Set to Integer Mode */, m_resourceProvider, this, nullptr); |
this (here: an instance of
CalculatorManager) gets passed as an argument to the newly created
CCalcEngine as
ICalcDisplay pointer and the engine is stored as
unique_ptr member field of
CalculatorManager.
In the destructor of CalculatorManager, a single function is called, MemorizedNumberClearAll which then invokes ProcessCommand(IDC_MCLEAR) on current engine, gets passed on to CCalcEngine::ProcessCommandWorker, to DisplayNum, to CCalcEngine::SetPrimaryDisplay and finally to m_pCalcDisplay->SetPrimaryDisplay, but here m_pCalcDisplay was the instance of CalculatorManager that just got its destructor called.
|
this->MemorizedNumberClearAll(); |
|
m_currentCalculatorEngine->ProcessCommand(IDC_MCLEAR); |
|
ProcessCommandWorker(wParam); |
|
DisplayNum(); // Causes 3.000 to shrink to 3. on first op. |
|
SetPrimaryDisplay(GroupDigitsPerRadix(m_numberString, m_radix)); |
|
m_pCalcDisplay->SetPrimaryDisplay(szText, isError); |
It will likely differ by implementation on how exactly, but the standard suggests that will invoke the pure virtual ICalcDisplay::SetPrimaryDisplay. In case of GCC I believe the vtable is already destroyed by the time you enter dtor's body.
My question is: why is it necessary to call MemorizedNumberClearAll in CalculatorManager::~CalculatorManager()? The calc manager and all its engines are going down anyway, maybe it's ok to just drop that and it should fix the described problem.
Device and Application Information
Get-AppxPackage : The term 'Get-AppxPackage' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:22
+ " - Architecture: $((Get-AppxPackage -Name Microsoft.WindowsCalculato ...
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-AppxPackage:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Get-AppxPackage : The term 'Get-AppxPackage' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:29
+ " - Application Version: $((Get-AppxPackage -Name Microsoft.WindowsCa ...
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-AppxPackage:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
- Application Version:
- Region: pl-PL
Get-AppxPackage : The term 'Get-AppxPackage' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:41
+ " - Dev Version Installed: $($null -ne (Get-AppxPackage -Name Microso ...
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-AppxPackage:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException