Re: Debug Assertion Failure

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



See below...
On Sat, 16 Jun 2007 08:41:28 -0700, katz911@xxxxxxxxx wrote:

On Jun 16, 5:58 pm, MrAsm <m...@xxxxxxx> wrote:
On Sat, 16 Jun 2007 01:21:55 -0700, katz...@xxxxxxxxx wrote:
Here is CUser_IO's definition:

class CUser_IO
{
public:
string UserName;
string Password;
long ID;
E_Clearance Clearance;
};
Regarding serializing using XML or another mechanism, I'd gladly do
that, but that would be against the project's definition (it's a
university project).

If you need to have a binary file where you store several records of
the same size, you might want doing like so:

// User record (fixed size)
struct UserData
{
char UserName[ MAX_USER_NAME_CHARS ];
char Password[ MAX_PASSWORD_CHARS ];
long ID;
... etc. ...
};

If you define UserData in this way, with only primitive data types
(char, long, etc. fixed-size arrays of these primitive types, *no*
pointers, *no* classes, like std::string), then you are allowed to
write records to file with a single call to fwrite, and read them back
with fread, and clear record with memset.

UserData userData;

// Clear record
memset( &userData, 0, sizeof(userData) );
// ...there is also the ::ZeroMemory Win32 function.

// Read one record from file
fread( &userData, sizeof(userData), 1, file );

etc.

(Note that I used 'char' because I think you are using std::string, so
maybe you are ignoring Unicode. But more correct Windows programming
style would consist in using TCHAR instead of 'char', to make the code
Unicode aware.)

Then you could copy the read data to the C++ class (more robust to
manage, because it has 'string' and not raw char arrays):

class CUser_IO
{
public:
string UserName;
string Password;
long ID;
E_Clearance Clearance;

// Member function to set fields
// from UserData structure
void Set( const UserData & userData )
{
UserName = userData.UserName;
Password = userData.Password;
... etc.
}

You might also define a construct like this:

CUser_IO::CUser_IO( const UserData & userData )
: UserName( userData.UserName ),
Password( userData.Password ),
etc...
{
}

and then write code like so:

// Build the CUser_IO class from data
// read from binary file
CUser_IO myUser( userData );

// Use myUser C++ class now
...

Moreover, I've read in your previous post that you are using VC++6.
VC++2005 has a better compiler, which can detect several error
conditions that VC++6 was unable to detect. Microsoft very kindly
offers the Express Edition of Visual C++ 2005; you might consider
downloading it and test the non-MFC part of your code (VC++2005
Express does not support MFC or ATL); maybe the new smarter and more
advanced VC++2005 compiler can help you better localize the bug in
your code.

Moreover, if you use VC++6 and STL classes, you may download STLport
and use it instead of VC++6 STL implementation:

http://www.stlport.org

or apply Dinkumware's patches to VC++6 STL:

http://www.dinkumware.com/vc_fixes.html

MrAsm

I tried switching to c-style strings (char arrays), and poof - the
problem is gone!
****
Yes. Because there you are not violating the type model. The structure contains all the
bytes inside itself, and there are no pointers referencing what is going on. Imagine if
instead of doing
TCHAR name[SIZE];
you had used the type
LPTSTR name;
then imagine what your would have done had you written out the second structure and read
it back in. Nothing useful would come out of it.

Generally, you should not try to do binary output of any kind of structure, because that
is not robust under maintenance. If you want to write out a structure (a class), add
methods to that class to cause it to serialize itself. What you got away with here is
essentially a hack: by making sure there was no substructure to violate, you were able to
write data out, but it only works in very restricted scenarios. You should adopt a more
robust mechanism to move data in and out of programs.
joe
****

The strange part is that before I integrated the file handler with the
MFC part, everything was working with strings as well. I have no idea
why integrating caused this problem.

Anyway, MrAsm, thanks for all the time you put into this issue! You're
a life saver :)
Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.



Relevant Pages