C++ wmi代码泄漏

C++ wmi代码泄漏,c++,C++,我从中复制并修改了一段代码 它的内存正在泄漏。请帮忙 #include "querysink.h" int main(int argc, char **argv) { HRESULT hres; hres = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hres)) { cout << "Failed to initialize COM library. Error code = 0x" &

我从中复制并修改了一段代码

它的内存正在泄漏。请帮忙

#include "querysink.h"


int main(int argc, char **argv)
{
HRESULT hres;
hres =  CoInitializeEx(0, COINIT_MULTITHREADED); 
if (FAILED(hres))
{
    cout << "Failed to initialize COM library. Error code = 0x" 
        << hex << hres << endl;
    return 1;                  // Program has failed.
}



hres =  CoInitializeSecurity(
    NULL, 
    -1,                          // COM authentication
    NULL,                        // Authentication services
    NULL,                        // Reserved
    RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication 
    RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  
    NULL,                        // Authentication info
    EOAC_NONE,                   // Additional capabilities 
    NULL                         // Reserved
    );


if (FAILED(hres))
{
    cout << "Failed to initialize security. Error code = 0x" 
        << hex << hres << endl;
    CoUninitialize();
    return 1;                    // Program has failed.
}



IWbemLocator *pLoc = NULL;

hres = CoCreateInstance(
    CLSID_WbemLocator,             
    0, 
    CLSCTX_INPROC_SERVER, 
    IID_IWbemLocator, (LPVOID *) &pLoc);

if (FAILED(hres))
{
    cout << "Failed to create IWbemLocator object."
        << " Err code = 0x"
        << hex << hres << endl;
    CoUninitialize();
    return 1;                 // Program has failed.
}


IWbemServices *pSvc = NULL;


hres = pLoc->ConnectServer(
    _bstr_t(L"ROOT\\CIMV2"), 
    NULL,
    NULL,
    0,
    NULL,
    0,
    0, 
    &pSvc
    );

if (FAILED(hres))
{
    cout << "Could not connect. Error code = 0x" 
         << hex << hres << endl;
    pLoc->Release();     
    CoUninitialize();
    return 1;                // Program has failed.
}

cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl;




hres = CoSetProxyBlanket(
   pSvc,                        // Indicates the proxy to set
   RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
   RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
   NULL,                        // Server principal name 
   RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
   RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
   NULL,                        // client identity
   EOAC_NONE                    // proxy capabilities 
);

if (FAILED(hres))
{
    cout << "Could not set proxy blanket. Error code = 0x" 
        << hex << hres << endl;
    pSvc->Release();
    pLoc->Release();     
    CoUninitialize();
    return 1;
}


QuerySink* pResponseSink = new QuerySink();
hres = pSvc->ExecQueryAsync(
    bstr_t("WQL"), 
    bstr_t("SELECT * FROM Win32_NTLogEvent"),
    WBEM_FLAG_BIDIRECTIONAL, 
    NULL,
    pResponseSink);

if (FAILED(hres))
{
    cout << "Query for log collection failed."
        << " Error code = 0x" 
        << hex << hres << endl;
    pSvc->Release();
    pLoc->Release();
    pResponseSink->Release();
    CoUninitialize();
    return 1;
}


while(pResponseSink->IsDone()==false){
        Sleep(100);
        }


pSvc->Release();
pLoc->Release();
CoUninitialize();
while(1)
{
 //do other job here
}


return 0;   // Program successfully completed.

}//end of file
#包括“querysink.h”
int main(int argc,字符**argv)
{
HRESULT hres;
hres=CoInitializeX(0,Conit_多线程);
如果(失败(hres))
{

CUT< P>检查文档,也就是你的变量清除错误,你基本上滥用它的用法,考虑在你的for循环中移动变量和释放你的变量。你通过引用获取变量,并且在完成每个变量之后,在获得C中的下一个对象的属性之前,应该清除它。ode>apObjArray
因为您将获得一个不同的对象。您的代码所做的只是释放每个变量的最后一个引用。另外,由于您对所有
Get
调用都使用相同的
HRESULT
对象,这意味着如果任何调用失败,您将无法释放属性,这将导致泄漏

考虑将代码替换为以下内容:

for (int i = 0; i < lObjectCount; i++)
{

         VARIANT writtenTime,genTime,logFile,eventCode,eventId,eventType,category;  
         BSTR strTimeWrittenProp = SysAllocString(L"TimeWritten");   
         hres = apObjArray[i]->Get(strTimeWrittenProp, 0, &writtenTime, 0, 0);   
         SysFreeString(strTimeWrittenProp); 

         //... Get other properties

         VariantClear( &writtenTime );
         //..clear variants before moving to next object in array
    enter code here
    if (FAILED(hres))
    {
        cout << "Failed to get the data from the query"
            << " Error code = 0x"
            << hex << hres << endl;
        return WBEM_E_FAILED;       // Program has failed.
    }


}
for(int i=0;iGet(strtimewritenprop,0,&writentime,0,0);
SysFreeString(strtimewritenprop);
//…获取其他属性
VariantClear(&WriteTime);
//..在移动到阵列中的下一个对象之前清除变体
在这里输入代码
如果(失败(hres))
{

你怎么知道它在泄漏?你观察到泄漏发生的条件是什么?你知道什么时候发生?泄漏有多大?发生的频率是多少?
    if (FAILED(hres))
    {
        cout << "Failed to get the data from the query"
            << " Error code = 0x"
            << hex << hres << endl;
        return WBEM_E_FAILED;       // Program has failed.
    }


}
VariantClear(&writtenTime);
VariantClear(&genTime);
VariantClear(&category);
VariantClear(&eventCode);
VariantClear(&eventId);
VariantClear(&eventType);
VariantClear(&logFile);

return WBEM_S_NO_ERROR;
}

HRESULT QuerySink::SetStatus(
        /* [in] */ LONG lFlags,
        /* [in] */ HRESULT hResult,
        /* [in] */ BSTR strParam,
        /* [in] */ IWbemClassObject __RPC_FAR *pObjParam
    )
{
if(lFlags == WBEM_STATUS_COMPLETE)
{
    printf("Call complete.\n");

    EnterCriticalSection(&threadLock);
    bDone = true;
    LeaveCriticalSection(&threadLock);
}
else if(lFlags == WBEM_STATUS_PROGRESS)
{
    printf("Call in progress.\n");
}

return WBEM_S_NO_ERROR;
}


bool QuerySink::IsDone()
{
bool done = true;

//  EnterCriticalSection(&threadLock);
done = bDone;
//  LeaveCriticalSection(&threadLock);

return done;
}    // end of querysink.cpp
#ifndef QUERYSINK_H
#define QUERYSINK_H

#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <comdef.h>
#include <Wbemidl.h>

# pragma comment(lib, "wbemuuid.lib")

class QuerySink : public IWbemObjectSink
{
LONG m_lRef;
bool bDone;
CRITICAL_SECTION threadLock; // for thread safety

public:
QuerySink() { m_lRef = 0; bDone = false; 
    InitializeCriticalSection(&threadLock); }
~QuerySink() { bDone = true;
    DeleteCriticalSection(&threadLock); }

virtual ULONG STDMETHODCALLTYPE AddRef();
virtual ULONG STDMETHODCALLTYPE Release();        
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,
    void** ppv);

virtual HRESULT STDMETHODCALLTYPE Indicate( 
        LONG lObjectCount,
        IWbemClassObject __RPC_FAR *__RPC_FAR *apObjArray
        );

virtual HRESULT STDMETHODCALLTYPE SetStatus( 
        /* [in] */ LONG lFlags,
        /* [in] */ HRESULT hResult,
        /* [in] */ BSTR strParam,
        /* [in] */ IWbemClassObject __RPC_FAR *pObjParam
        );

bool IsDone();
};

#endif    // end of querysink.h
for (int i = 0; i < lObjectCount; i++)
{

         VARIANT writtenTime,genTime,logFile,eventCode,eventId,eventType,category;  
         BSTR strTimeWrittenProp = SysAllocString(L"TimeWritten");   
         hres = apObjArray[i]->Get(strTimeWrittenProp, 0, &writtenTime, 0, 0);   
         SysFreeString(strTimeWrittenProp); 

         //... Get other properties

         VariantClear( &writtenTime );
         //..clear variants before moving to next object in array
    enter code here
    if (FAILED(hres))
    {
        cout << "Failed to get the data from the query"
            << " Error code = 0x"
            << hex << hres << endl;
        return WBEM_E_FAILED;       // Program has failed.
    }


}