Steps to Reproduce Behavior
- Create an empty console application project in Microsoft Visual C++.
- Insert the following sample code that updates one field of the same record repeatedly:
#undef EOF
#import "C:\Program Files\Common Files\System\Ado\msado15.dll" no_namespace
void main(void)
{
_RecordsetPtr rs;
HRESULT hr = CoInitialize(NULL);
try
{
hr = rs.CreateInstance(__uuidof(Recordset));
rs->CursorLocation = adUseClient;
rs->Fields->Append("BSTRString",adBSTR,10,adFldUpdatable);
hr = rs->Open(vtMissing,vtMissing,adOpenStatic,adLockOptimistic,-1);
hr = rs->AddNew();
rs->Fields->GetItem("BSTRString")->Value = OLESTR("");
//make the leak here
//update the first record repeatedly
_bstr_t bstrTest("Text to update field to.");
rs->MoveFirst();
for (int i = 0; i < 100000; i++)
{
rs->Fields->GetItem("BSTRString")->Value = bstrTest;
rs->Update();
}
rs->Close();
}
catch(_com_error& e) {
_bstr_t bstrErrorMessage(e.ErrorMessage());
_bstr_t bstrDescription(e.Description());
}
}
- Compile and run the application.
- Watch this process with PerfMon, and you will notice a steady increase in the Private Bytes counter for the process, similar to what happens with a memory leak.
Affected Data Types
The following types of fields all are subject to this behavior:
Collapse this tableExpand this table
Type | Size |
---|
adBSTR | any |
adChar | >255 |
adVarChar | >255 |
adLongVarChar | any |
adWChar | >127 |
adVarWChar | >127 |
adLongVarWChar | any |
To prevent the memory increase, use the preceding chart to choose a data type that is not affected by this behavior. For example, an adChar of size 255 or smaller. Closing the recordset frees the memory as well.