_bstr_t утечка памяти

У меня есть код C ++. Но это не освобождение памяти должным образом. Скажите, где я не прав, вот мой код

1 void MyClass::MyFunction(void)
2 {
3    for (int i=0; i<count; i++)
4    {
5        _bstr_t xml = GetXML(i);
6        // some work
7        SysFreeString(xml);
8    }
9 }

GetXML (строка 5) возвращает мне BSTR. При этом память программы увеличивается. Но после SysFreeString (строка 7) память не освобождается. Что я здесь не так делаю?

3

Решение

Первый:

// This makes a copy.
// This is where the leak is. You are leaking the original string.
_bstr_t xml = GetXML();

// You want to use this, to attach the BSTR to the _bstr_t
_bstr_t xml = _bstr_t(GetXML(), false);

Во-вторых, не делай этого:

SysFreeString(xml);

_bstr_t класс сделает это за вас.

В-третьих, BSTR не сразу освобождает память для ОС, он кэширует недавно использованные строки, чтобы ускорить SysAllocString. Вы не должны ожидать, что использование памяти будет происходить сразу после SysFreeString.

Вы можете контролировать это поведение в целях отладки:

Наконец, при просмотре использования памяти в диспетчере задач вам нужно смотреть на столбец «Фиксированный размер», а не «Рабочий набор». Перейдите в Меню-> Вид-> Выбрать столбцы, чтобы отобразить столбец. Также обратите внимание, что это действительно помогает только в течение определенного периода времени — память не может быть сразу освобождена для ОС, но если у вас нет утечек, она не будет расти вечно в течение нескольких часов.

7

Другие решения

Я полагаю, вы должны использовать:

xml.Attach(GetXML(i));

оператор = выглядит так, как будто он фактически присваивает новое значение — что означает его копирование. Это значение, возвращаемое GetXML, остается несвободным.

также не должно быть необходимости в SysFreeString (xml);

1

Диспетчер задач предоставляет только объем памяти, выделенный для процесса. Когда C ++ освобождает память (C освобождает), он не обязательно возвращает память операционной системе, поэтому диспетчер задач не обязательно будет показывать, как работает память, пока процесс не завершится.

Диспетчер задач может показать, что если вы продолжаете выделять память и не освобождаете ее, тогда объем памяти процесса будет увеличиваться, если это произойдет, вы, вероятно, испытываете утечку памяти.

При программировании вам нужно использовать профилировщики памяти, чтобы увидеть, освобождаете ли вы память. В Windows я использовал Rational Purify, чтобы дать мне эту информацию, но она стоит дорого. MS C runtime может использоваться для отслеживания памяти. MSDN Здесь представлен обзор, прочитайте и перейдите по ссылке.

Что касается вашего кода, а также других комментариев и ответов, один из пунктов использования класса _bstr_t — это управление памятью и другими ресурсами, поэтому вам не следует вызывать SysFreeString.

0