Microsoft KB Archive/887805

= A memory leak occurs when you run a CDO application that is written in C++ =

Article ID: 887805

Article Last Modified on 5/2/2006

-

APPLIES TO

 Microsoft Collaboration Data Objects 2.0, when used with:  Microsoft Visual C++ 2005 Express Edition

 Microsoft Visual C++ .NET 2003 Standard Edition

 Microsoft Visual C++ .NET 2002 Standard Edition

 Microsoft Visual C++ 6.0 Professional Edition</li></ul>

 Microsoft Visual C++ 6.0 Standard Edition</li></ul> </li></ul>

-

<div class="notice_section">

<div class="symptoms_section">

SYMPTOMS
When 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.

<div class="cause_section">

CAUSE
This 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.

<div class="resolution_section">

RESOLUTION
To 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(&quot;HRESULT    : %lx\r\nMinor Code : %lx\r\nSource     : %s\r\nDescription: %s\n&quot;),                    ErrorInfo.hrError,                    ErrorInfo.dwMinor,                    bstrSourceOfError,                    bstrDescriptionOfError); // Free the resources. SysFreeString(bstrDescriptionOfError); SysFreeString(bstrSourceOfError); pErrorInfoRec->Release; }       }        pErrorRecords->Release; }   pErrorInfo->Release; }

<div class="moreinformation_section">

MORE INFORMATION
You can generally confirm whether a memory leak exists by monitoring the following counter in Performance Monitor: Performance Object: Process Instance: YourApplication.exe Counter: Private Bytes Note  is a placeholder for the name of the C++ application.

Keywords: kbtshoot kbcode kbcdo kbexpertiseinter KB887805

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.