Утечка памяти с CComPtr - PullRequest
       35

Утечка памяти с CComPtr

0 голосов
/ 03 мая 2019

Я использую crtdbg для определения позиции утечки, и у меня возникает утечка памяти при вызове new

CComPtr<IDBColumnInfo> m_spColumnInfo
CComPtr<CDBColumnInfo> spResult = new CDBColumnInfo(); //Memory leak here
//another logic come here to set data to spResult
//another logic come here to set data to spResult
//another logic come here to set data to spResult
m_spColumnInfo = static_cast<IDBColumnInfo*>(spResult.Detach());
spResult.Release();

Есть ли какие-либо действия, которые необходимо выполнить с spResult?

1 Ответ

1 голос
/ 03 мая 2019

У вас утечка памяти, потому что вы неправильно управляете счетчиком ссылок на объект CDBColumnInfo.

Когда вы инициализируете spResult, refcount объекта инициализируется равным 1. Когда вы вызываете spResult.Detach(), объект все еще имеет refcount 1, так как Detach() не уменьшает его. Когда отсоединенный указатель затем присваивается m_spColumnInfo, отсчет объекта увеличивается до 2. Когда позднее освобождается m_spColumnInfo, это уменьшает счет объекта до 1, и объект просачивается.

Вы вообще не должны отделять spResult. Присвойте его как есть m_spColumnInfo, что увеличит refcount до 2, а затем позволит spResult нормально выйти из области видимости, уменьшив refcount до 1, оставив m_spColumnInfo с единственной активной ссылкой. Когда позже будет выпущен m_spColumnInfo, счет будет уменьшен до 0, и объект будет освобожден.

Вы вообще не должны пытаться управлять счетом вручную. Это побеждает всю цель использования CComPtr.

CComPtr<IDBColumnInfo> m_spColumnInfo;

...

{
    CComPtr<CDBColumnInfo> spResult = new CDBColumnInfo();
    //set data to spResult
    m_spColumnInfo = spResult;
}

Кроме того, отметим, что ваша функция вообще не имеет деловых вызовов CoInitialize() и CoUninitialize()! Вам необходимо удалить эти вызовы из вашей функции (тем более что ваша функция даже не вызывает CoUninitialize() в большинстве путей кода, которые выходят из вашей функции). Эти звонки не являются обязанностью вашей функции. Это поток, который вызывает вашу функцию, чтобы решить, как ей нужно инициализировать COM для себя. Эти функции COM должны вызываться только один раз для потока, а не для пользовательской функции.

...