Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

MFC assertion in DBRFX.CPP - 'field address has changed'

208 views
Skip to first unread message

Ed Barrett

unread,
Jul 10, 1998, 3:00:00 AM7/10/98
to
I've seen the above assertion occur in my application. Since there's
nothing about this in the FAQ, I thought I'd post a request for help:


The assertion occurs in line 274 of dbrfx.cpp. A trace message of also
appears:
Error: field address (column 6) has changed!

I am using VC 5 SP3. As far as I can see what's happening is this:

The application talks to an ODBC-compliant database, using the MFC ODBC
classes. My CRecordset-derived class holds a number of data members,
including a number of CStrings. At a certain point, AddNew() is called
on the open recordset. I believe that this performs an ODBC bind operation
with each of the data members' data. Then the new data is added to the
recordset. For primitive datatypes this isn't a problem - while the data
may have changed, the address in which such data is held has not.

However with a CString object, it is possible that in assigning a new
(larger) value, that the CString object is forced to re-allocate memory.
So now the earlier AddNew() operation which was meant to bind that CString's
data to a particular column is now invalidated. As a result, the debug
version of MFC throws up this assertion.

Questions:
1. Is my diagnosis essentially correct?
2. The best way around this?


Ed Barrett
Software Developer
Sysgenics Ltd.


Steve Miller

unread,
Jul 10, 1998, 3:00:00 AM7/10/98
to
You are right that the address of the CString has changed since the SQL
bind. The RFX_Text() function (in DBRFX.CPP) calculates the required buffer
size during the bind processing. It then locks the buffer so that the
address of the buffer doesn't change. However, the address of the buffer
will change when a CString that is larger then the calculated buffer size is
assigned to the locked CString.

We had problems when we used CString::Format() on the CRecordset data
members. Format() attempts to calculate the size of the destination string
based on the format characters. It's an estimate that is often way larger
than necessary.

You can get around this problem by using an intermediate CString:

CString strTemp;

strTemp.Format("%s", m_strField1);
m_strField1 = strTemp;

I hope this helps!

--
Steve
To reply, change .com to .gov

Ed Barrett wrote in message ...

0 new messages