C++ WMI не могу понять, где здесь утечка памяти

201
27 сентября 2017, 11:11

Вот функция, перепробовал десятки вариантов, но не могу понять, где здесь утекает память? Проверял банальным вызовом функции 1000 раз, забирало около 17 мб.

SystemInfo::SystemInfo(QString lpRemoteName)
{
    objIWbemLocator = new QAxObject("WbemScripting.SWbemLocator");
        if (!objIWbemLocator)
        qDebug("Не создался WbemScripting.SWbemLocator");
      objWMIService = objIWbemLocator->querySubObject(
              "ConnectServer(QString&,QString&)", //objWMIService - объявляем как переменную член класса, память выделяем в конструкторе
              lpRemoteName, QString("root\\cimv2")); // пространство имен. Если и домен и рабочая группа, можно прикрутить аутентификацию
      if (!objWMIService)
        qDebug("Не создался WMIService");
      objIWbemLocator->deleteLater();
}
SystemInfo::~SystemInfo()
{
    objIWbemLocator->clear();
    objIWbemLocator->deleteLater();
    objWMIService->clear();
    objWMIService->deleteLater();
    item->deleteLater();
}
QVector<QPair<QString, QString> > SystemInfo::getPointingDevices()
{
    QVector<QPair<QString, QString>> vec;
    query = QString("SELECT * FROM Win32_PointingDevice");
    IEnumVARIANT *enumInterface = halfInitialize();
    if (enumInterface != nullptr)
    {
        for (int i = 0; i < objInterList->dynamicCall("Count").toInt(); i++)
        {
            if (initializeItem(enumInterface))
            {
                vec.push_back(QPair<QString, QString>("Имя устройства ввода", item->dynamicCall("Name").toString()));
                vec.push_back(QPair<QString, QString>("Описание устройства ввода", item->dynamicCall("Description").toString()));
                vec.push_back(QPair<QString, QString>("Id устройства ввода", item->dynamicCall("DeviceID").toString()));
                vec.push_back(QPair<QString, QString>("Интерфейс устройства ввода", item->dynamicCall("DeviceInterface").toString()));
                vec.push_back(QPair<QString, QString>("Тип устройства ввода", item->dynamicCall("HardwareType").toString()));
              item->deleteLater();
            }
        }
        enumInterface->Release();
    }
    return vec;
}
IEnumVARIANT* SystemInfo::halfInitialize()
{
    objInterList = objWMIService->querySubObject("ExecQuery(QString&))", query);
    if (!objInterList)
      return nullptr;
    if (objInterList->dynamicCall("Count").toInt() == 0)
      return nullptr;
    QAxObject *enum1 = objInterList->querySubObject("_NewEnum");
    if (!enum1)
      return nullptr;
    IEnumVARIANT* enumInterface = 0;
    enum1->queryInterface(IID_IEnumVARIANT, (void**)&enumInterface);
    enum1->deleteLater();
    if (!enumInterface)
      return nullptr;
    enumInterface->Reset();
    return enumInterface;
}
bool SystemInfo::initializeItem(IEnumVARIANT *enumInterface)
{
    VARIANT *theItem = (VARIANT*)malloc(sizeof(VARIANT));
    if (enumInterface->Next(1,theItem,NULL) == S_FALSE)
      return false;
    item = new QAxObject((IUnknown*)theItem->punkVal);
    free(theItem);
    if (!item)
    {
        item->deleteLater();
        return false;
    }
    return true;
}
Answer 1

Тут не полное описание класса, но думаю вы не учитываете что querySubObject создает новый объект, который будет удален только после удаления родительского, т.е. objWMIService (пологаю, что он находится за циклом и переиспользуется много раз). Еще одно место "enum1->deleteLater();". Объект не будет удален, пока EventLoop не прокрутится. Т.е. если внутри цикла вы не отдаете управление в EventLoop, то объекты у вас копятся до лучших времен.

P.S. Про malloc/delete и использование после удаления вам уже написали.

READ ALSO
Установка пароля на HDD языком C++

Установка пароля на HDD языком C++

Придумал задачу и пытаюсь ее решить: хочу поставить пароль на жесткий диск, и сделать это на C++При помощи каких библиотек/классов это можно...

171
Как редактировать страницы tabcontrol

Как редактировать страницы tabcontrol

Как редактировать страницы tabcontrol в c++? Я добавил на Dialog новый tab, как добавить новую страницу к tabcontrol и расположить на ней(странице) элементы?...

166
Как на C++ подключиться к MySQL по SLL вручную (без MySQL Connector)?

Как на C++ подключиться к MySQL по SLL вручную (без MySQL Connector)?

Предлагаемая разработчиками MySQL библиотека "Connector" слишком много весит - больше всего файла установщика моего приложения, и даже больше распакованного...

205
Qt не меняется стиль окна

Qt не меняется стиль окна

Имеется примерно следующего содержания файл gameconstantsh:

265