问题描述
我想写 OPcclient,但问题出在内存泄漏上。
这是我从 OPCServer 读取值的功能
VARIANT copcclient::ReadValue(LPWSTR szItemID) {
IOPCItemmgt* pItemmgt = NULL;
tagOPCITEMDEF* pItems;
tagOPCITEMRESULT* pResult = NULL;
HRESULT* pErrors = NULL;
tagOPCITEMSTATE* pItemValue = NULL;
HRESULT hRes;
DWORD updaterate = 1000;
long bActive = 1;
pItemmgt = NULL;
//Добавление группы
if (m_hGroup != 0) {
hRes = m_pOPCServer->RemoveGroup(m_hGroup,1);
m_hGroup = 0;
}
hRes = m_pOPCServer->AddGroup((LPWSTR)(L"MyGroup"),bActive,updaterate,1,NULL,&m_hGroup,&updaterate,(GUID*)&__uuidof(IOPCItemmgt),(IUnkNown**)&pItemmgt);
//Добавление элементов в группу
DWORD dwCount = 1;
pItems =
(tagOPCITEMDEF*)CoTaskMemAlloc(dwCount * sizeof(tagOPCITEMDEF));
pResult = NULL;
pErrors = NULL;
pItems[0].szItemID = szItemID;
pItems[0].szAccesspath = NULL;
pItems[0].bActive = TRUE;
pItems[0].hClient = 0;
pItems[0].vtRequestedDataType = VT_EMPTY;
pItems[0].dwBlobSize = 0;
pItems[0].pBlob = NULL;
hRes = pItemmgt->AddItems(1,pItems,&pResult,&pErrors);
IOPCSyncIO* pSyncIO = NULL;
IID IID_IOPCSYNCIO = __uuidof(IOPCSyncIO);
hRes = pItemmgt->QueryInterface(IID_IOPCSYNCIO,(void**)&pSyncIO);
pItemValue = NULL;
Sleep(50);
hRes = pSyncIO->Read(OPC_DS_CACHE,&pResult->hServer,&pItemValue,&pErrors);
VARIANT res = pItemValue->vDataValue;
pSyncIO->Release();
CoTaskMemFree(pSyncIO);
CoTaskMemFree(pItemValue);
pItemmgt->Release();
CoTaskMemFree(pItemmgt);
CoTaskMemFree(pErrors);
CoTaskMemFree(pResult->pBlob);
CoTaskMemFree(pResult);
CoTaskMemFree(pItems);
return res;
}
我在一些网站上(确实如此)发现我需要从 hResult->pBlob 中释放内存,但这没有帮助。 我确定 AddItems 中存在该问题。 VS19 说我在这个函数中丢失了 0.02 Kb。
如果您需要有关程序或解决方案的更多信息,请写下您想要的内容。
解决方法
这可能不是完整的答案(这取决于值中的数据类型),但在执行 CoTaskMemFree(pItemValue) 之前,您还应该执行 VariantClear(pItemValue->vDataValue)。这可能是 Read 部分的泄漏,但它只会在字符串或其他类型的本身具有附加指针的 VARIANT 中显示。
但是,如果您正在寻找与 AddItems 相关的泄漏:您不会释放从 AddItems 获得的 pError。您只是释放了从 Read 中获得的 pError。