问题
I have this piece of C++ code:
static CString timeout(_T("TIMEOUT"));
if(strError.Left(7).CompareNoCase(timeout) == 0) return TRUE;
In my immediate windows, I see following value for strError
:
? strError
L""
ATL::CSimpleStringT<wchar_t,1>: L""
I'm getting following exception (I'm debugging a crash dump):
Unhandled exception at 0x74B4A9F2 in CRASH.DMP: Microsoft C++ exception:
COleException at memory location 0x01BFFD14. occurred
My call stack is the following:
KERNELBASE.dll!_RaiseException@16() Unknown
msvcr110.dll!_CxxThrowException(void * pExceptionObject, const _s__ThrowInfo * pThrowInfo) Line 152 C++
mfc110u.dll!AfxThrowOleException(long) Unknown
mfc110u.dll!ATL::AtlThrowImpl(long) Unknown
mfc110u.dll!ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > >::CompareNoCase(wchar_t const *) Unknown
> <Application>.exe!<Own_Class>::<Own_Function>(const ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > & strError) Line 106 C++
As I was having a crash while checking .Left(7)
of an empty string, I immediately assumed this was the course of the issue. However I've realised that this piece of code generally is working fine (I just double-checked this), and while having a second look, I see that the exception if not an access violation or a nullpointerexception, but an Ole related exception. In the meanwhile I've understood that the issue's not within the strError.Left(7)
part: it seems to be the CompareNoCase()
method, going wrong, but how?
Can anybody enlighten me what's doing wrong in my code?
As far as strError
is concerned, it gets created as follows:
CString strError;
...
strError = <function>();
where <function>()
is something like:
CString <function>(){
...
return _T("fix string"); // or:
return <Complicated_function_handling>();
In this particular case, I have no idea how strError
has been created (I know it's empty, as clearly seen in the immediate window, but I only have the crash dump, so I can read current values, but I don't know their history).
One thing, which might be helpful: I've asked for the memory address of strError
, and I've looked at the data within memory (using Visual Studio Memory debug window), and I get following data:
5c 18 9c 71 38 d9 ca 00 03 00 00 00 cc 3d c2 00 70 fe bf 01 94 13 b3 00 39 00 00 00 80 fe bf 01 be 58 aa 00 b0 3d c2 00 10 0c cd 00 44 03 00 00 01 00 00 00 d3 5f ac 00 8a 40 1d 72 8e f2 d6 73
Thanks in advance
回答1:
Working my thru the source for MFC, the exception is being thrown because timeOut
is a NULL string. Common ways that this can happen are if it has not been constructed yet, or it has been destroyed. The error code stored within the COleException
is E_FAIL
.
The call sequence goes something like this:
CompareNoCase
callsAtlIsValidString
(which will return false in your case iftimeOut
, when converted to aconst char *
, is NULL).- Since
AtlIsValidString
returns false, the code associated with theATLENSURE
macro callsAtlThrow(E_FAIL)
(AtlThrow
is a macro that is defined asATL::AtlThrowImpl
. AtlThrowImpl
callsAfxThrowOleException
since the error code is notE_OUTOFMEMORY
.
来源:https://stackoverflow.com/questions/54666981/how-can-a-simple-string-comparison-cause-an-oleexception