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. |