Да, ==
плохо для сравнения Строк (любые объекты действительно, если Вы не знаете, что они являются каноническими). ==
просто сравнивает ссылки на объект. .equals()
тесты для равенства. Для Строк часто они будут тем же, но поскольку Вы обнаружили, это всегда не гарантируется.
Анельсон рассмотрел это довольно хорошо, но я хотел добавить пару моментов;
CoTaskMemAlloc - не единственный COM-дружественный распределитель - BSTR распознаются маршаллером по умолчанию, и будет освобожден / перераспределен с помощью SysAllocString и друзей.
Во избежание USES_CONVERSION (из-за риска переполнения стека - см. ответ Анельсона) ваш полный код должен быть примерно таким [1]
(обратите внимание, что A2BSTR безопасен использовать, поскольку он вызывает SysAllocString после преобразования и не использует динамическое выделение стека. Кроме того, используйте удаление массива (delete []), поскольку BuildResponse, вероятно, выделяет массив символов)
[1]
HRESULT MyClass::ProcessRequest(BSTR request, BSTR* pResponse)
{
char* pszResponse = BuildResponse(CW2A(request));
*pResponse = A2BSTR(pszResponse);
delete[] pszResponse;
return S_OK;
}
Я не вижу очевидная проблема с вашим кодом. Предлагаем вам изменить метод ProcessRequest, чтобы исключить COM-взаимодействие как источник утечки:
HRESULT MyClass::ProcessRequest(BSTR request, BSTR* pResponse)
{
*psResponse = ::SysAllocStringLen(L"[suitably long string here]");
return S_OK;
}
Я подозреваю, что утечки не будет, и в этом случае вы сузили утечку до своего кода.
Я также хотел бы отметить OLE2A выделяет память в стеке, поэтому вы не только не должны удалять pszRequest, но и вообще не должны использовать OLE2A из-за возможности переполнения стека. См. эту статью для более безопасных альтернатив.
Я также предлагаю вам заменить A2BSTR на :: SysAllocString (CA2W (pszResponse))
Думаю, вам нужно уничтожить запрос
с помощью :: SysFreeString ()
. Эта память выделяется на стороне сервера.
Кроме того, OLE2A
может выделять память из-за преобразования (посмотрите). Вы также не освобождаете его.