I have BSTR string which is passed from COM server. When I put this string into _bstr_t (or CComBSTR) constructor then access violation is occurred. I checked this exception and found that this exception raised only when BSTR is empty (or null).
I was trying to put nulled BSTR explicitly to _bstr_t constructor and this works fine:
BSTR bstr = NULL;
_bstr_t t(bstr, false); 
cout << t.length() << endl;
But with BSTR which is passed from COM server this don't work - access violation exception is ocurred when string is empty or null (or maybe corrupted?)
I found that this workaround works fine:
if (SysStringLen(bstrFromCOMserver) > 0) {
    _bstr_t t(bstrFromCOMserver, false);    
    cout << t.length() << endl;
}
But I want to know why this don't work directly with _bstr_t or CComBSTR wrappers:
_bstr_t t(bstrFromCOMserver, false);
if (t.length() > 0) {...}
Update:
How COM server pass BSTR string:
void CALLBACK CProxy_ISTIQuoteEvents::OnSTIQuoteSnap(const structSTIQuoteSnap& structQuoteSnap) const { 
        if (SysStringLen(structQuoteSnap.bstrUpdateTime) > 0) {
            _bstr_t updateTime(structQuoteSnap.bstrUpdateTime, false);
        }
    }
}
 
                        
The
OnSTIQuoteSnapmethods belongs to an event sink and is called back by the server, as we clarified in the comments. Thus, the server (as the caller) keeps the ownership overstructQuoteSnapstructure and all of its fields.updateTimeis a local smart-pointer variable that should be making a copy of the string (structQuoteSnap.bstrUpdateTime), but it doesn't (asfalseis passed to its constructor), so it rather takes over the BSTR's memory. This memory is freed as soon asupdateTimegoes out of scope. The server knows nothing about that and may continue usingbstrUpdateTimeand may eventually try to free the same memory twice.