Re: ado memory leak? - source provided
- From: "Scot T Brennecke" <ScotB@xxxxxxxxxxxxxxxxxx>
- Date: Fri, 2 Sep 2005 23:57:13 -0500
When tracking down a memory leak, it helps to know more clues than just "there's a leak". For
instance, is it one big blob of memory, or several identical smaller ones. If many, how big are
they? What type of memory allocation does it appear to be that's leaking? What clues can you get
from the contents of the leaked memory blocks?
"khalprin" <khalprin@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:2EE2C086-5A16-425F-8167-BABB1E0D4ED4@xxxxxxxxxxxxxxxx
> I'm trying to find a memory leak in my code that uses ADO and have a sample
> that exhibits the leak. I started with some sample code from Matt Neerincx
> (thank you) and modified it to resemble the way it is executed in my program
> and a COM
> component.
>
> The test includes a loop which:
> 1. connects to the database (jet)
> 2. executes a command to delete records from a table
> 3. executes a command (3 times) to add a record to the table
> 4. disconnects
>
> I've constructed the test using commands in stored procedures, and using
> commands as text with and without parameters. Compiling each way results in
> the leak. The code is below. Can anyone
> point out the leak?
>
> Thanks.
>
>
> #include "stdafx.h"
> #include <atlbase.h>
> //#include "Test2.h"
> #include "conio.h"
>
> #pragma warning( push )
> #pragma warning( disable : 4146 )
> #import "c:\Program Files\Common Files\system\ado\msadox.dll"
> #import "c:\Program Files\Common Files\system\ado\msado15.dll"
> rename("EOF","EndOfFile")
> #pragma warning( pop )
>
> #ifdef _DEBUG
> #define new DEBUG_NEW
> #undef THIS_FILE
> static char THIS_FILE[] = __FILE__;
> #endif
>
> //#define USE_CMDPROC
> //#define USE_PARAMS
>
> void RunSample();
> ADODB::_ConnectionPtr GetJetConnection();
> void RunSingleLoop();
> void Reset(ADODB::_ConnectionPtr conn);
> void AddRecords(ADODB::_ConnectionPtr conn);
>
> /////////////////////////////////////////////////////////////////////////////
> // The one and only application object
>
> CWinApp theApp;
>
> using namespace std;
>
> int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
> {
> int nRetCode = 0;
>
> // initialize MFC and print and error on failure
> if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
> {
> // TODO: change error code to suit your needs
> cerr << _T("Fatal Error: MFC initialization failed") << endl;
> return -1;
> }
>
> CoInitialize(NULL);
> RunSample();
> CoUninitialize();
>
> return nRetCode;
> }
>
> #define LOOP_COUNT 100000 // Number of loops to execute.
>
> void RunSample()
> {
>
> #if defined(USE_CMDPROC) && defined(USE_PARAMS)
> #error ("Invalid configuration")
> #endif
>
> ADODB::_ConnectionPtr global_conn = NULL;
> int i;
>
> try
> {
> // Open global conn to keep Jet loaded (perf).
> global_conn = GetJetConnection();
>
> try
> {
> global_conn->Execute(L"drop table
> T1",NULL,ADODB::adExecuteNoRecords|ADODB::adCmdText);
> }
> catch ( _com_error ex )
> {
>
> }
>
> global_conn->Execute(L"create table T1(f1 int, f2
> int)",NULL,ADODB::adExecuteNoRecords|ADODB::adCmdText);
>
> for (i=1; i<=LOOP_COUNT; i++ )
> {
> RunSingleLoop();
>
> Sleep(5);
> if ( 0 == (i%1000))
> {
> printf( "Completed %08lu of %08lu iterations.\n", i, LOOP_COUNT );
> while ( _kbhit() )
> {
> int x = _getch();
> if ( 'Q' == x || 'q' == x )
> {
> return;
> }
> }
> }
> }
> }
>
> catch( _com_error ex )
> {
> // Robust error trapping left as an exercise for the reader. (G)
> ASSERT(FALSE);
> }
>
> return;
> }
>
> _bstr_t JET_CONNECT(L"Provider=Microsoft.Jet.OLEDB.4.0;Data
> Source=C:\\NW99.mdb;");
>
> ADODB::_ConnectionPtr GetJetConnection()
> {
> HRESULT hr;
> ADODB::_ConnectionPtr conn = NULL;
>
> hr = conn.CreateInstance( __uuidof(ADODB::Connection) );
> //if ( FAILED( hr ) ) throw( _com_error( hr, NULL ) );
>
> conn->CursorLocation = ADODB::adUseServer;
>
> // Open connection.
> conn->Open( JET_CONNECT, "", "", -1L );
> //Setting this property doesn't help.
> //conn->Properties->Item["Jet OLEDB:Max Buffer Size"]->Value = 500L;
>
> return conn;
> }
>
> void RunSingleLoop()
> {
> ADODB::_ConnectionPtr conn = NULL;
>
> // Open local conn for loop.
> conn = GetJetConnection();
>
> Reset(conn);
>
> // The AddRecords generate the memory leaks
> AddRecords(conn);
> AddRecords(conn);
> AddRecords(conn);
>
> conn->Close();
> conn = NULL;
> }
>
> void Reset(ADODB::_ConnectionPtr conn)
> {
> ADODB::_CommandPtr cmd = NULL;
> CComVariant v1;
>
> HRESULT hr = cmd.CreateInstance( __uuidof(ADODB::Command) );
>
> /*
> Query: qdMissingData
>
> PARAMETERS P1 Long;
> DELETE * FROM T1 WHERE f1=P1;
> */
>
> cmd->ActiveConnection = conn;
> #ifdef USE_CMDPROC
> cmd->CommandText = L"qdMissingData";
> cmd->CommandType = ADODB::adCmdStoredProc;
> #else
> #ifdef USE_PARAMS
> cmd->CommandText = L"DELETE * FROM T1 WHERE f1=?";
> #else
> cmd->CommandText = L"DELETE * FROM T1 WHERE f1=1";
> #endif
> cmd->CommandType = ADODB::adCmdText;
> #endif
>
> #ifdef USE_PARAMS
> v1 = 1L;
> cmd->Parameters->Append(cmd->CreateParameter(
> L"P1",ADODB::adInteger,ADODB::adParamInput,-1, v1));
> v1.Clear();
> #endif
>
> cmd->Execute(NULL,NULL,ADODB::adExecuteNoRecords);
>
> cmd->ActiveConnection = NULL;
> cmd = NULL;
> }
>
> void AddRecords(ADODB::_ConnectionPtr conn)
> {
> ADODB::_CommandPtr cmd = NULL;
> CComVariant v1;
> CComVariant v2;
> static long lCounter = 1;
>
> // Now create parameterized ADO call.
> HRESULT hr = cmd.CreateInstance( __uuidof(ADODB::Command) );
> // if ( FAILED( hr ) ) throw( _com_error( hr, NULL ) );
>
> cmd->ActiveConnection = conn;
>
> /*
> Query: qiMissingRecord:
>
> PARAMETERS P1 Long, P2 DateTime;
> INSERT INTO T1 ( f1, f2 ) VALUES (P1, P2);
> */
>
> // Create insert statement and setup params.
> #ifdef USE_CMDPROC
> cmd->CommandText = L"qiMissingRecord";
> cmd->CommandType = ADODB::adCmdStoredProc;
> #else
> #ifdef USE_PARAMS
> cmd->CommandText = L"INSERT INTO T1 ( f1, f2 ) VALUES (?, ?)";
> #else
> cmd->CommandText = L"INSERT INTO T1 ( f1, f2 ) VALUES (1, 2)";
> #endif
> cmd->CommandType = ADODB::adCmdText;
> #endif
>
> #ifdef USE_PARAMS
> v1 = 1L;
> v2 = lCounter++;
> cmd->Parameters->Append(cmd->CreateParameter(
> L"P1",ADODB::adInteger,ADODB::adParamInput,-1, v1));
> cmd->Parameters->Append(cmd->CreateParameter(
> L"P2",ADODB::adInteger,ADODB::adParamInput,-1, v2));
> v1.Clear();
> v2.Clear();
> #endif
>
> // Execute statement.
> cmd->Execute(NULL,NULL,ADODB::adExecuteNoRecords);
>
> // Cleanup
> cmd->ActiveConnection = NULL;
> cmd = NULL;
> }
>
.
- Follow-Ups:
- Re: ado memory leak? - source provided
- From: khalprin
- Re: ado memory leak? - source provided
- Prev by Date: RE: Invoke VBA functions
- Next by Date: Help: Building a COM object returning and ADO recordset in VS.NET 2003
- Previous by thread: RE: Invoke VBA functions
- Next by thread: Re: ado memory leak? - source provided
- Index(es):
Relevant Pages
|