2014-09-11 2 views
1

Я получаю нарушение доступа, которое я не могу понять при попытке сравнить с строками BSTR в функции C++. По какой-то причине код работает обычно большую часть времени. Но иногда, казалось бы, случайным образом, это исключает. Это то, что я делаю:Нарушение прав доступа на CompStr (BSTR, BSTR) после получения строки?

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 является:

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

    *outStr = ::SysAllocString(m_memberString); 

    return S_OK; 
} 

Я получаю нарушение прав доступа в CompStr, который:

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); 
} 

Любые идеи о том, что я делаю неправильно или почему это неудачно?

+1

Вы уверены, что и '' str1' и str2' оба были выделены с 'SysAllocString'? –

+0

Я уверен, что они есть. Я знаю, что моя строка (str2) инициализируется, но я буду копать глубже в другие пути кода, чтобы увидеть, не инициализируется ли str1. – climbak

+0

В отладчике проверьте значение 'str2'. Также может быть неопределенное поведение раньше (например, переполнение буфера), и только когда вы выделяете другую строку, это повреждение появляется. –

ответ

1

Вы не инициализируете myString и не проверяете результат GetString().

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; 
} 

Кроме того, убедитесь, что someOtherString выделяется как BSTR, иначе SysStringLen() не будет работать на нем. Я бы предложил изменить CompStr() вместо WCHAR* и lstrlenW(). Вы можете передать BSTR к WCHAR*:

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

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

К сожалению, я ограничена BSTR, но я посмотрю на someOtherString и посмотрю, есть ли у нее какие-либо пути в коде другого, где это не инициализируется. Спасибо за советы. – climbak

+0

@climbak Вам не нужно инициализировать 'myString', поскольку вы установили в' GetString', и не удалось проверить возвращаемое значение 'SysAllocString' не приведет к сбою' SysStringLen', потому что он возвращает 0, если передан указатель NULL. Однако изменение кода для использования 'lstrlenW' или' wcslen' стоит попробовать, если он приведет к поведению вашего кода по-разному. –

+0

Если это, по-видимому, исправляет проблему, то OP, должно быть, не правильно присвоил 'str1', так что это должно быть исправлено в противном случае одна и та же проблема может отображаться только в другом фрагменте кода. –