Microsoft KB Archive/155721

= FIX: Access Violation in RFX_Date If CTime Not Initialized =

Article ID: 155721

Article Last Modified on 11/21/2006

-

APPLIES TO

 Microsoft Foundation Class Library 4.2, when used with:  Microsoft Visual C++ 4.2 Enterprise Edition

 Microsoft Visual C++ 4.2 Professional Edition 

-



This article was previously published under Q155721



SYMPTOMS
An application may fail with an access violation while executing the RFX_Date function. A message similar to the following appears:

Unhandled exception in My.exe (MFC42D.DLL):

0xC0000005: Access Violation.



CAUSE
The RFX_Date function in MFC 4.2 now requires initialization of CTime objects. Versions of MFC earlier than 4.2 do not have this requirement. AppWizard and ClassWizard do not initialize the CTime member variables for you.

Because CTime member variables are not initialized in the CRecordset constructor, an access violation can occur when RFX_Date tries to use the uninitialized data.



RESOLUTION
Initialize the CTime member variables in the constructor of your CRecordset- derived class. The following is one way to initialize the CTime member variable: m_myTime = CTime::GetCurrentTime;

<div class="status_section">

STATUS
This problem was corrected in the MFC AppWizard included with Microsoft Visual C++, version 5.0. CTime member variables are now assigned a value of zero by the AppWizard. If a CRecordset class is manually added to your project that contains an empty recordset you still need to initialize the CTime member variable as explained in the RESOLUTION section.

<div class="moreinformation_section">

MORE INFORMATION
Here is one common scenario where you may see an access violation:

Call CRecordset::AddNew on an empty recordset, set the value of the Ctime member variable, and then call CRecordset::Update.

The insert to the database works; however, an access violation may occur before the call to Update returns.

The following steps show how the access violation occurs:

<ol> After the insert to the database is complete, Update attempts to reload the data for the previous record using the CRecordset::LoadFields function.</li> LoadFields calls CRecordset::DoFieldExchange, which calls the RFX_Date function for the CTime field.</li>  The CFieldExchange::LoadField case within RFX_Date calls CTime::GetYear: void AFXAPI RFX_Date(CFieldExchange* pFX, LPCTSTR szName, CTime&                          value) {         ...          switch (pFX->m_nOperation) {             ....              case CFieldExchange::LoadField: {                 ...                  pts->year = (SWORD)value.GetYear; ...             }          ...      }                        </li></ol>

The definition for GetYear in AFX.INL dereferences the pointer returned from GetLocalTm(NULL): _AFX_INLINE int CTime::GetYear const { return (GetLocalTm(NULL)->tm_year) + 1900; } GetLocalTm returns the value from localtime, which is a NULL pointer if the CTime value is a negative number. Because CTime has not been initialized, it may have a negative value. When GetYear attempts to dereference this NULL pointer, the access violation occurs in AFX.INL at line 265.

Additional query words: crash gpf exception kbDatabase kbMFC kbVC420bug kbVC500fix kbDSupport KBDSD

Keywords: kbbug kbcode kberrmsg kbfix kbvc500fix KB155721

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.