A memory leak occurs when you run a CDO application that is written in C++ (887805)
The information in this article applies to:
- Collaboration Data Objects (CDO), when used with:
- Microsoft Visual C++ 2005 Express Edition
- Microsoft Visual C++ .NET (2003)
- Microsoft Visual C++ .NET (2002)
- Microsoft Visual C++, 32-bit Professional Edition 6.0
- Microsoft Visual C++ Standard Edition, version 6.0
SYMPTOMSWhen you run a Collaborative Data Objects (CDO)
application that is written in Microsoft C++, a memory leak occurs. The memory
usage of the CDO application process may grow steadily over a long time. Additionally, a
gradual decrease in application performance may occur. Over time, the value of the Private Bytes counter for the CDO application may continue to increase.CAUSEThis problem can occur when the application uses CDO to
access a field in a message. Error objects may not be disposed of correctly
when the following conditions are true:
- A call to the get_Value method successfully returns.
- The VARIANT parameter that is passed into the get_Value method has the Variant type (vt) set to VT_EMPTY when the method returns.
This causes the memory leak. RESOLUTIONTo resolve this problem, test for the current error object
by calling the GetErrorInfo method, and then dispose of the errors accordingly. The following
is a code example. if( SUCCEEDED( hr = field->get_Value( &value )))
{
if( value.vt == VT_EMPTY )
{
CheckErrors();
}
else
{
// Do something useful with the information.
}
}
void CheckErrors()
{
IErrorInfo* pErrorInfo = NULL;
IErrorInfo* pErrorInfoRec = NULL;
IErrorRecords* pErrorRecords = NULL;
ULONG i, ulNumErrorRecs = 0;
ERRORINFO ErrorInfo = {0};
DWORD MYLOCALEID = 0x409;
HRESULT hRes = S_OK;
// Obtain the current error object. Return if no
// error object exists.
hRes = GetErrorInfo(0,&pErrorInfo);
if (!pErrorInfo) return;
// Obtain the IErrorRecord interface, and then obtain the count
// of error records.
hRes = pErrorInfo->QueryInterface(IID_IErrorRecords, (void**)&pErrorRecords);
if (pErrorRecords)
{
pErrorRecords->GetRecordCount(&ulNumErrorRecs);
// Read through error records and display them.
for (i = 0; i < ulNumErrorRecs; i++)
{
// Get basic error information.
pErrorRecords->GetBasicErrorInfo(i, &ErrorInfo);
// Get error description and source through the
// IErrorInfo interface pointer on a particular record.
pErrorRecords->GetErrorInfo(i, MYLOCALEID, &pErrorInfoRec);
if (pErrorInfoRec)
{
BSTR bstrDescriptionOfError = NULL;
BSTR bstrSourceOfError = NULL;
hRes = pErrorInfoRec->GetDescription(&bstrDescriptionOfError);
hRes = pErrorInfoRec->GetSource(&bstrSourceOfError);
// At this point, you can call GetCustomErrorObject
// and query for additional interfaces to determine
// what else occurred.
wprintf(
OLESTR("HRESULT : %lx\r\nMinor Code : %lx\r\nSource : %s\r\nDescription: %s\n"),
ErrorInfo.hrError,
ErrorInfo.dwMinor,
bstrSourceOfError,
bstrDescriptionOfError);
// Free the resources.
SysFreeString(bstrDescriptionOfError);
SysFreeString(bstrSourceOfError);
pErrorInfoRec->Release();
}
}
pErrorRecords->Release();
}
pErrorInfo->Release();
}
Modification Type: | Major | Last Reviewed: | 5/2/2006 |
---|
Keywords: | kbCDO kbExpertiseInter kbtshoot kbcode KB887805 kbAudDeveloper |
---|
|