Question

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);
        }
    }
}
Was it helpful?

Solution

The OnSTIQuoteSnap methods 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 over structQuoteSnap structure and all of its fields. updateTime is a local smart-pointer variable that should be making a copy of the string (structQuoteSnap.bstrUpdateTime), but it doesn't (as false is passed to its constructor), so it rather takes over the BSTR's memory. This memory is freed as soon as updateTime goes out of scope. The server knows nothing about that and may continue using bstrUpdateTime and may eventually try to free the same memory twice.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top