Special Data Types and Memory Leaking

        OleDBPro supports a lot of OLEDB defined data types. Some of them are special data types which must be carefully treated and their memories must be freed by a consumer if the consumer owns their memories. Otherwise, either memory leaking or other problems may happen. These special data types are DBTYPE_BSTR, DBTYPE_VARIANT, DBTYPE_PROVARIANT, DBTYPE_IUNKNOWN, DBTYPE_HCHAPTER, X|DBTYPE_BYREF, X|DBTYPE_ARRAY and X|DBTYPE_VECTOR (X represents an indicator of one of standard C data types). For most of providers, these data types are not native for them and you don't meet these special data types. However, you may need to force a provider to convert a standard C data type into one of these special data types for convenience, especially when you develop a COM object. This short article explains how to free provider-allocated memories for each of columns of a rowset or output parameters of a parameterized stored procedure.

        Currently, the CParamBase base classes or templates support four special data types, DBTYPE_BSTR, DBTYPE_VARIANT, DBTYPE_IUNKNOWN, and DBTYPE_PROVARIANT. When an output parameter of a stored procedure is set with one of the four data types, CPData::m_pData or CPInfoEx::m_pData can't be NULL and a caller must free them as shown in the following snippets after a provider sends their output parameter data to a client.

        BSTR                    bstrOutput=NULL;
        VARIANT              vtOutput;
        PROVARIANT     PvtOutput;

        VariantInit(&vtOutput);
        PropVariantInit(&PvtOutput);

       //suppose that a CBatchParam<T> is opened, an array of CPData structure is set and CBatchParam<T>::DoBatch is called.

        //free memories
  
     if(bstrOutput) SysFreeString(bstrOutput);
        VariantClear(&vtOutput);
        PropVariantClear(&PvtOutput);

        CRBase based classes and templates support all the above listed special data types. The following snippet codes show how to free memories of special data types for each of fetched records with use of CRBase::FreeRecordMemory.

        CBulkRecord<COTable<CRBase>  >    BulkRecord;
        void*               pBuffer=NULL;
        ULONG          nCols;
        DBTYPE        nDBType;

        //open BulkRecord successfully and set some columns with the above special data types here.

        BulkRecord.MoveFirst();
        while(!BulkRecord.IsEOF()){

                //retrieve and show data here

   
             //free all the provider-allocated memories in the current record
                BulkRecord.FreeRecordMemory();

                //update or add record here


               
BulkRecord.MoveNext();
        }

        A caller may use CRBase::GetDataEx to retrieve data with one of above special data types. To see how to free it, click here.