C++ MFC

Moderators: Lundin
Number of threads: 3354
Number of posts: 9032

This Forum Only
Post New Thread
Single Post View       Linear View       Threaded View      f

Report
Serialization produces memory fault -- even in this TINY class! Posted by __c4.ep on 20 May 2003 at 7:36 AM
This message was edited by __c4.ep at 2003-5-20 7:37:21

Alright, I've tried everything over the last 5 hours, but I just can't get this code to work.

What I want to do is to serialize a class in an SDI app (created with app wizard), which holds a list of another class holding a CString object. Here's the code:

// header

class COther
{
public:
	CString m_str;
};

class CData
{
public:

	void Serialize( CArchive& ar )
	{
		m_list.Serialize( ar );
	}

	CList<COther,COther&> m_list;
};


Then I instantiate CData in CSerializationDoc and add an object of COther to the list in CSerializationDoc's ctor:

CSerializationDoc::CSerializationDoc()
{
	// TODO: add one-time construction code here
	COther obj;
	obj.m_str = "Text";
	m_data.m_list.AddTail( obj );
}


Then I finally have my Serialization func:

void CSerializationDoc::Serialize(CArchive& ar)
{
	m_data.Serialize( ar );
}


Well, if I run this app and load a document, I'm getting memory faults when exiting the app. The errors occur in CStringData::Release().
Obviously, the app tries to release a CString which already HAS been released, thus trying to delete data where nothing is anymore.

Does anyone know what the heck is going wrong here?
I have already posted two times on codeguru.com but noone can help me there. Perhaps you can?


Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by stober on 20 May 2003 at 9:32 AM
This message was edited by stober at 2003-5-20 9:33:34

Interesting challenge if you don't know how to do it. Just need a couple minior changes
other.h

class COther 
{
public:
	COther();
	virtual ~COther();
	virtual void Serialize(CArchive& ar);
	CString	m_str;
};


other.cpp
void COther::Serialize(CArchive& ar)
{
	if(ar.IsStoring())
		ar.WriteString(m_str);
	else
		ar.ReadString(m_str);

}

MyDoc.cpp

template <> void AFXAPI SerializeElements <COther> ( CArchive& ar, COther* pNewOther, int nCount )
{
    for ( int i = 0; i < nCount; i++, pNewOther++ )
    {
        // Serialize each COther object
        pNewOther->Serialize( ar );
    }
}




Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by __c4.ep on 20 May 2003 at 9:50 AM
: Interesting challenge if you don't know how to do it. Just need a couple minior changes

First of all, thanks for your quick answer, I'll try this out immediately.

But frankly I still don't understand why the error occured. Could you explain what exactly went wrong there? I racked my brain on this one the whole day and I still don't get why it didn't work.

Thanks in advance.
Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by stober on 20 May 2003 at 9:59 AM
: : Interesting challenge if you don't know how to do it. Just need a couple minior changes
:
: First of all, thanks for your quick answer, I'll try this out immediately.
:
: But frankly I still don't understand why the error occured. Could you explain what exactly went wrong there? I racked my brain on this one the whole day and I still don't get why it didn't work.
:
: Thanks in advance.
:
I suspect it was because the template class didn't know how to serialize that COther class. You have to tell it how with the SerialzeObjects() template I added to the document class. After I added that, all the problems disappeared.

Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by __c4.ep on 20 May 2003 at 10:14 AM
: I suspect it was because the template class didn't know how to serialize that COther class. You have to tell it how with the SerialzeObjects() template I added to the document class. After I added that, all the problems disappeared.
:
Well, thanks a ton :)

Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by __c4.ep on 20 May 2003 at 10:19 AM
Oh one more question real quick:

When exactly do I have to use the DECLARE_SERIAL/IMPLEMENT_SERIAL macros? Actually my first thought was that I have to make my COther class known to the Serialization system using those macros.

But obviously it works without them. *confused*

Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by stober on 20 May 2003 at 10:50 AM
: Oh one more question real quick:
:
: When exactly do I have to use the DECLARE_SERIAL/IMPLEMENT_SERIAL macros? Actually my first thought was that I have to make my COther class known to the Serialization system using those macros.
:
: But obviously it works without them. *confused*
:
:
In your case, it doesn't matter whether you use it or not. If you want to use it for some other reason, then CObject (or some other class derived from CObject) needs to be COther's base class.

The macros are used when the type of object in the file is unknown until runtime. The file contains information about the class that was previously written there during serialzation using the << and >> CArchive operators. You don't need this feature because you know exactly what class the data in the file belongs to and because the CList class allocates memory for them before it calls COther class's serialize function.

Clear as mud?

Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by __c4.ep on 20 May 2003 at 11:58 AM
: Clear as mud?

Somewhat yeah. Sounds like a RTTI mechanism. Although RTTI is still a big ? for me, I think I basically got what you mean. :)
Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by Federal102 on 21 May 2003 at 11:25 AM
: Oh one more question real quick:
:
: When exactly do I have to use the DECLARE_SERIAL/IMPLEMENT_SERIAL macros? Actually my first thought was that I have to make my COther class known to the Serialization system using those macros.
:
: But obviously it works without them. *confused*
:
:
If you want to use the macros, the following should work....

The first thing you need to do is derive all of your classes from CObject. Then you implement the Serializable function for in each class.
(BTW: I gave up trying to use CList and replaced it with std::list)

class COther: public CObject
{
DECLARE_SERIAL(COther)
public:
	COther(){}
	COther(const COther &rhs)
	{
		m_str = rhs.m_str;
	}
	CString m_str;
	COther & operator = (COther &rhs)
	{
		m_str = rhs.m_str;
		return *this;
	}
	void Serialize(CArchive &ar)
	{
		CObject::Serialize (ar);
		if (ar.IsStoring ())
			ar << m_str;
		else // Loading, not storing
			ar >> m_str;
	}

};

class CData : public CObject 
{
DECLARE_SERIAL(CData)
public:
	CData();
	virtual ~CData();
	list<COther> m_list;
	void Serialize(CArchive &ar)
	{
		CObject::Serialize (ar);
		if (ar.IsStoring ())
		{
			for(list<COther>::iterator i = m_list.begin(); i != m_list.end(); ++i)
			{
				i->Serialize(ar);
			}
		}

		else
		{// Loading, not storing
			for(list<COther>::iterator i = m_list.begin(); i != m_list.end(); ++i)
			{
				i->Serialize(ar);
			}	
		}
	}

};


In your Data.cpp file you need to include

IMPLEMENT_SERIAL(COther, CObject, 1)
IMPLEMENT_SERIAL(CData, CObject, 1)


And finally in your doc

CSerializationDoc::CSerializationDoc()
{
	// TODO: add one-time construction code here
	COther obj;
	obj.m_str = "Hello World";
	p = new CData;
	p->m_list.push_back(obj);
}

void CSerializationDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
		p->Serialize(ar);
		AfxMessageBox("Saving");
	}
	else
	{
		// TODO: add loading code here
		p->Serialize(ar);
		// Following for testing only//
		CString temp;
		list<COther>::iterator i = p->m_list.begin();
		temp = i->m_str;
		AfxMessageBox("Retrieving");
		AfxMessageBox(temp);
	
	}
}


Have to admit the Prosise book was a BIG help
Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by __c4.ep on 21 May 2003 at 4:34 AM
I'm currently trying to implement your solution but I'm still having problems:

If I define that function template, the compiler tells me that SerializeElements has already been defined in another file:

[i]SWGCB error LNK2005: "void __stdcall SerializeElements(class CArchive &,class CSkillMod *,int)" (?SerializeElements@@YGXAAVCArchive@@PAVCSkillMod@@H@Z) already defined in Character.obj[/i]

The function is placed in my Document Class' cpp file.
Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by stober on 21 May 2003 at 6:22 AM
: I'm currently trying to implement your solution but I'm still having problems:
:
: If I define that function template, the compiler tells me that SerializeElements has already been defined in another file:
:
: [i]SWGCB error LNK2005: "void __stdcall SerializeElements(class CArchive &,class CSkillMod *,int)" (?SerializeElements@@YGXAAVCArchive@@PAVCSkillMod@@H@Z) already defined in Character.obj[/i]
:
: The function is placed in my Document Class' cpp file.
:
I had a similary problem in the example I gave you earlier. So I just moved that function to the top of the file that the compiler complained about and it fixed it. You will probably have to do the same. Move the function to the top of Character.cpp.
Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by __c4.ep on 21 May 2003 at 7:38 AM
Now I'm getting the following error (it's the same I described in the email, don't know if you've already read it, I've sent it through this board):

error C2908:
explicit specialization; 'void SerializeElements(CArchive &,CSkill *,INT_PTR)' has already been instantiated from the primary template
Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by stober on 21 May 2003 at 9:04 AM
: Now I'm getting the following error (it's the same I described in the email, don't know if you've already read it, I've sent it through this board):
:
: error C2908:
: explicit specialization; 'void SerializeElements(CArchive &,CSkill *,INT_PTR)' has already been instantiated from the primary template
:
I can't access my personal e-mail account from where I am at.[/code]
Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by __c4.ep on 21 May 2003 at 9:08 AM
This message was edited by __c4.ep at 2003-5-21 9:12:25

I fixed that error (had to define the SerializeElements() function BEFORE any header includes occured).

But now guess what... I'm still getting those memory faults. It's a vicious circle, I can tell you. :(

Oh and:
Does it make a difference if I use CArchive::WriteString and CArchive::ReadString or << and >> to store/read CStrings. Perhaps that's the source of all evil, I don't know. I always used the streaming operators because the MSDN said that they were overloaded for CString objects. But when I have a look at the strings read out from the archive after opening a file I doubt that... They are totally crippled. Seems that even the saving doesn't work properly.


Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by __c4.ep on 21 May 2003 at 9:18 AM
This message was edited by __c4.ep at 2003-5-21 9:18:52

Hah, I have found something out:

The Serialize() method of the class which objects are stored in said list is never called! That means the CList::Serialize() method is still making bit-wise copies of the contained objects which would explain that I still have memory faults.

But this would mean as well that the definition of that template function is worthless, or at least the CList simply ignores it, because I call the serialization method of the stored object inside this function (as you told me).

This is getting weirder with every minute I work on this problem.


Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by stober on 21 May 2003 at 10:07 AM
compile for debug and put a breakpoint in that SerializeObject() function to see if its actualy getting called or not. I think the parameters to it have to be identical to how you created the CList object in the first place. Of course the alternative is not to use the Serialize method of that CList template, but to do your own thing.
Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by __c4.ep on 21 May 2003 at 11:37 AM
: compile for debug and put a breakpoint in that SerializeObject() function to see if its actualy getting called or not. I think the parameters to it have to be identical to how you created the CList object in the first place. Of course the alternative is not to use the Serialize method of that CList template, but to do your own thing.
:

I did, the function is not called, never.

What I recognized though is that a little question mark appears on the breakpoint when compiling for debug. What does that mean? Perhaps the compiler ignores my function? I'm using Visual C++ 7.
Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by stober on 21 May 2003 at 11:45 AM
: I did, the function is not called, never.
That means you have defined it incorrectly.

:
: What I recognized though is that a little question mark appears on the breakpoint when compiling for debug. What does that mean? Perhaps the compiler ignores my function? I'm using Visual C++ 7.
:


I can't help you with the ? question -- I don't have that compiler. I use VC 6.
Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by __c4.ep on 21 May 2003 at 12:34 PM
This message was edited by __c4.ep at 2003-5-21 12:35:8

: : I did, the function is not called, never.
: That means you have defined it incorrectly.

template <> void AFXAPI SerializeElements <CSkill> ( CArchive& ar, CSkill* pElement, int nCount )
{
    for ( int i = 0; i < nCount; i++, pElement++ )
        pElement->Serialize( ar );
}


whereas CSkill is the class which objects are being hold in the list. I defined the function at the very top of the cpp file, even before any includes occur. Otherwise I would get said error.

What's wrong with the definition? CSkill::Serialize() is of course defined as well, but -- obviously -- not called either.


Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by stober on 21 May 2003 at 1:40 PM
:
: template <> void AFXAPI SerializeElements <CSkill> ( CArchive& ar, CSkill* pElement, int nCount )
: {
:     for ( int i = 0; i < nCount; i++, pElement++ )
:         pElement->Serialize( ar );
: }
: 

:

did you declare the CList object like this?
CList<CSkill> list;


Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by __c4.ep on 22 May 2003 at 3:30 AM
: did you declare the CList object like this?
:
: CList<CSkill> list;
: 


No, like this:
CList<CSkill,CSkill&> list;



Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by stober on 22 May 2003 at 3:53 AM
See the example in the private e-mail I sent you last night. That should solve your problem. Let me know if you didn't get it.
Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by __c4.ep on 22 May 2003 at 4:59 AM
: See the example in the private e-mail I sent you last night. That should solve your problem. Let me know if you didn't get it.
:

Yeah I got it and already sent you an answer.
Actually I do it pretty much the same, just that I always get those errors when defining the template function SerializeElements().

Btw, why do you use the CArchive Read/Write functions instead of the streaming operators?
Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by stober on 22 May 2003 at 6:07 AM
: Btw, why do you use the CArchive Read/Write functions instead of the streaming operators?
:

habit. I had some problems once reading back CString. Also, I work with UNICODE (English language only) a great deal and the stream operators produce different file format.
Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by __c4.ep on 22 May 2003 at 7:04 AM
: : Btw, why do you use the CArchive Read/Write functions instead of the streaming operators?
: :
:
: habit. I had some problems once reading back CString. Also, I work with UNICODE (English language only) a great deal and the stream operators produce different file format.
:

Ah ok, good to know.

Do you have any idea why i'm getting those errors when defining SerializeElements() as described above? Weird eh?
Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by stober on 22 May 2003 at 7:45 AM
: Do you have any idea why i'm getting those errors when defining SerializeElements() as described above? Weird eh?
:

No, I don't know. But I'm not really all that good with templates anyway. Post that question on www.codeguru.com -- they have several members that are pretty darned good at it.
Report
Re: Serialization produces memory fault -- even in this TINY class! Posted by Dennis Dingen on 9 Jun 2003 at 3:51 AM
: This message was edited by __c4.ep at 2003-5-20 7:37:21

: Alright, I've tried everything over the last 5 hours, but I just can't get this code to work.
:
: What I want to do is to serialize a class in an SDI app (created with app wizard), which holds a list of another class holding a CString object. Here's the code:
:
:
: // header
: 
: class COther
: {
: public:
: 	CString m_str;
: };
: 
: class CData
: {
: public:
: 
: 	void Serialize( CArchive& ar )
: 	{
: 		m_list.Serialize( ar );
: 	}
: 
: 	CList<COther,COther&> m_list;
: };
: 

:
: Then I instantiate CData in CSerializationDoc and add an object of COther to the list in CSerializationDoc's ctor:
:
:
: CSerializationDoc::CSerializationDoc()
: {
: 	// TODO: add one-time construction code here
: 	COther obj;
: 	obj.m_str = "Text";
: 	m_data.m_list.AddTail( obj );
: }
: 

:
: Then I finally have my Serialization func:
:
:
: void CSerializationDoc::Serialize(CArchive& ar)
: {
: 	m_data.Serialize( ar );
: }
: 

:
: Well, if I run this app and load a document, I'm getting memory faults when exiting the app. The errors occur in CStringData::Release().
: Obviously, the app tries to release a CString which already HAS been released, thus trying to delete data where nothing is anymore.
:
: Does anyone know what the heck is going wrong here?
: I have already posted two times on codeguru.com but noone can help me there. Perhaps you can?
:
:
: Hi there, i've had exactly the same problem as you have..i wanted to save a sting by using serialization. I'm nog at home right know, but when i do, i'll send you my solution.. i can remember it had something do to with the CString object that wast created or something.

good luck


Grz,
Bl@ckBl@de <Feedback: void_void@hotmail.com>




 

Recent Jobs

Official Programmer's Heaven Blogs
Web Hosting | Browser and Social Games | Gadgets

Popular resources on Programmersheaven.com
Assembly | Basic | C | C# | C++ | Delphi | Flash | Java | JavaScript | Pascal | Perl | PHP | Python | Ruby | Visual Basic
© Copyright 2011 Programmersheaven.com - All rights reserved.
Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
Operated by CommunityHeaven, a BootstrapLabs company.