Search code examples
c++combstr

Access violation on CompStr(BSTR, BSTR) after getting string?


I am getting an access violation that I can't figure out when trying to compare to BSTR strings in a c++ function. For whatever reason, the code runs normally most of the time. But on occasion, seemingly randomly, it will throw the exception. This is what I'm doing:

BSTR myString; // also tried this with a CComBSTR, same result, but less often it seemed
pSomeObject->GetString(&myString);
if (!CompStr(someOtherString, myString))
{
  //do stuff
}

SomeObject::GetString is:

STDMETHODIMP SomeObject::GetString(BSTR* outStr)
{
  if (!outStr) return E_POINTER;

  *outStr = ::SysAllocString(m_memberString);

  return S_OK;
}

I'm getting the access violation in CompStr which is:

inline bool CompStr(BSTR str1, BSTR str2)
{
  UINT len1 = ::SysStringLen(str1);
  UINT len2 = ::SysStringLen(str2);  // this is where I'm getting the access violation

  return CompStr(str1, len1, str2, len2);
}

Any ideas on what I'm doing wrong or why it's failing?


Solution

  • You are not initializing myString, and not checking GetString() for an error result.

    BSTR myString = NULL; // CComBSTR initializes for you
    if (SUCCEEDED(pSomeObject->GetString(&myString)))
    {
        if (!CompStr(someOtherString, myString))
        {
            //do stuff
        }
    }
    

    STDMETHODIMP SomeObject::GetString(BSTR* outStr)
    {
        if (!outStr) return E_POINTER;
    
        *outStr = ::SysAllocString(m_memberString);
        if (!*outStr) return E_OUTOFMEMORY;
    
        return S_OK;
    }
    

    Also, make sure someOtherString is allocated as a BSTR, otherwise SysStringLen() will not work on it. I would suggest changing CompStr() to use WCHAR* and lstrlenW() instead. You can pass a BSTR to a WCHAR*:

    inline bool CompStr(WCHAR* str1, WCHAR* str2)
    {
        UINT len1 = ::lstrlenW(str1);
        UINT len2 = ::lstrlenW(str2);
    
        return CompStr(str1, len1, str2, len2);
    }