FIX: Deleting CRecordset Object Before Closing ItLast reviewed: September 18, 1997Article ID: Q113815 |
1.50 1.51
WINDOWS
kbprg kbfixlist kbbuglist
The information in this article applies to:
SYMPTOMSIf a CDatabase object is allocated and then passed into a CRecordset constructor the user may notice a memory leak if the CRecordset is deleted before calling CRecordset::Close(). Not only will memoryleak, but the following ODBC error may eventually occur when using snapshots (or more specifically, when using the cursor library):
General Error: Unable to create file buffer State:S1000 CAUSEA bug in the CRecordset destructor prevents the ::SQLFreeStmt() from getting called for the ODBC statement handle (HSTMT) used by the CRecordset object.
RESOLUTIONTo work around the problem, make sure that CRecordset::Close() is called before it is deleted. One way to handle this is to put a call to CRecordset::Close() in the destructor of the CRecordset-derived class.
STATUSMicrosoft has confirmed this to be a bug in the products listed at the beginning of this article. This bug was corrected in MFC version 3.0, included with Visual C++, 32-bit Edition, version 2.0.
MORE INFORMATIONThe CRecordset destructor has the following code:
CRecordset::~CRecordset() { if (!m_bRecordsetDb) m_pDatabase = NULL; ASSERT_VALID(this); TRY { Close(); if (m_bRecordsetDb) { delete m_pDatabase; m_pDatabase = NULL; } } ...The m_bRecordsetDb is a flag that the CRecordset class uses to tell whether the CRecordset created the CDatabase object or whether it was passed to the CRecordset in the constructor. If a program passes in the CDatabase pointer to the CRecordset, looking at the code you can see that m_pDatabase will be set to NULL. Unfortunately this causes a problem when Close() is called later in the function. In CRecordset::Close() the following lines determine whether the HSTMT allocated by the CRecordset needs to be freed:
if (m_pDatabase != SQL_NULL_HDBC) { AFX_SQL_SYNC(::SQLFreeStmt(m_hstmtUpdate, SQL_DROP)); }Since m_pDatabase has been set to NULL and the CDatabase object still exists, we run into a problem because SQL_NULL_HDBC is equal to NULL. Thus, the statement handle is never freed although the CRecordset goes away. This normally isn't too much of a problem because statement handles get freed when a connection goes away. However, if you are re-using a CDatabase for multiple CRecordset objects, many allocated HSTMTs will accumulate.
|
Additional reference words: 1.50 2.50 2.51 odbc
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |