Microsoft KB Archive/293349

= PRB: Retrieving Properties with OLE DB May Cause Memory Leak =

Article ID: 293349

Article Last Modified on 5/12/2003

-

APPLIES TO


 * Microsoft OLE DB 2.0
 * Microsoft OLE DB 2.1
 * Microsoft OLE DB 2.5
 * Microsoft OLE DB 2.6
 * Microsoft Data Access Components 2.7

-



This article was previously published under Q293349



SYMPTOMS
Whenever an OLE DB consumer application retrieves properties from the provider, it is the responsibility of the consumer application to free the memory associated with the property structures that the provider returns.

In some cases, however, freeing the property structures alone, as described in the OLE DB documentation, is not sufficient. Retrieving and freeing the properties will cause a memory leak in this case.



CAUSE
The DBPROPSET structures returned to the client by the provider contain a pointer to an array of DBPROP structures. The DBPROP structures have a VARIANT member called vValue. Because the vValue member could contain a pointer to a BSTR or other allocated memory on output, the vValue member should be cleared by the consumer application by calling the VariantClear function. The OLE DB documentation does not specify this.



RESOLUTION
Call VariantClear on the vValue member of every DBPROP structure in every DBPROP array before freeing the DBPROP array.



STATUS
This behavior is by design.



MORE INFORMATION
The following OLE DB functions return property information to the consumer:
 * IDBProperties::GetProperties
 * IRowsetIndex::GetIndexInfo
 * ICommandProperties::GetProperties
 * IRowsetInfo::GetProperties
 * ISessionProperties::GetProperties

Steps to Reproduce Behavior
The following sample code demonstrates the code that will leak memory:
 * 1) include 
 * 2) include 


 * 1) include 
 * 2) define DBINITCONSTANTS
 * 3) include 

int main(int argc, TCHAR * argv[]) {   IDataInitialize*    pIDataInitialize = NULL; IDBInitialize*     pIDBInitialize = NULL; IDBProperties*     pIDBProperties = NULL; int                iLoopMax = 10000; int                iLoop; UINT               iSet; DBPROPSET*         pPropsets = NULL; unsigned long      cPropertyIDSets = 0 ; unsigned long      cPropertySets = 0 ; DBPROPIDSET        rgPropertyIDSets[1]; HRESULT hr; //If needed, change the connection string here. OLECHAR* wszInitString = L&quot;Provider=SQLOLEDB.1;User ID=sa;Initial Catalog=pubs;Data Source=(local);&quot;; hr = CoInitialize(NULL); hr = CoCreateInstance( CLSID_MSDAINITIALIZE,        NULL,         CLSCTX_INPROC_SERVER,         IID_IDataInitialize,         ( void ** ) & pIDataInitialize ); hr = pIDataInitialize->GetDataSource(NULL, CLSCTX_INPROC_SERVER, wszInitString,       IID_IDBInitialize, ( IUnknown ** ) & pIDBInitialize ); hr = pIDBInitialize->Initialize;

hr = pIDBInitialize->QueryInterface(IID_IDBProperties, (void**) &pIDBProperties);

rgPropertyIDSets[0].rgPropertyIDs      = NULL ; rgPropertyIDSets[0].cPropertyIDs       = 0 ; rgPropertyIDSets[0].guidPropertySet    = DBPROPSET_DATASOURCE; for (iLoop = 0; iLoop < iLoopMax; iLoop++) {       hr = pIDBProperties->GetProperties   ( cPropertyIDSets,                                                rgPropertyIDSets,                                                &cPropertySets,                                                &pPropsets) ; for (iSet = 0; iSet < cPropertySets; iSet++ ) {              DBPROP *  pr = pPropsets[iSet].rgProperties;

//NOTE :Uncomment the following lines to remove the memory leak //int iProp; //for (iProp = 0; iProp < pPropsets[iSet].cProperties;iProp++) //{           //  VariantClear( &(pr[iProp].vValue) ); //}

CoTaskMemFree(pr); }       CoTaskMemFree(pPropsets); Sleep(1); }

hr = pIDBInitialize->Uninitialize; if (pIDBProperties) {       pIDBProperties->Release; }   if (pIDBInitialize) {       pIDBInitialize->Release; }

if (pIDataInitialize) {       pIDataInitialize->Release; }   return 0 ; } To free the memory correctly, uncomment the loop in the code above to free each individual VARIANT member before freeing the DBPROP array.

Keywords: kbconsumer kbdatabase kbprb KB293349

-

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

© Microsoft Corporation. All rights reserved.