• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 524
  • Last Modified:

Serializing CArray

Is serializing CArray any different from serializing any other object derived from CObject? I am trying to serialize an CArray of PContact structs. I don't get any errors or warnings, but when I read the contents of one of the elements of the array, it comes out like junk... then crashes the program. I will post code if needed. BTW, struct PContact contains CString objects... would that effect the results because CString uses pointers?
0
RMD010799
Asked:
RMD010799
1 Solution
 
RMD010799Author Commented:
Edited text of question
0
 
migelCommented:
Your program crushes due to CArray::serealize store memory dump of the items, so when reading stored CString object you get wrong pointers. Best way to avoid this problem is write own code for imlpement serealization.

0
 
RMD010799Author Commented:
When you say write my own code for the serialzation... do you mean for serialize CArray or for serializing each of my PContact structs?
0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
migelCommented:
CArray do not call any serealization functions of the stored objects by default. So you need to serealize size of the array and each stored object manually.

for example:
void SerealizeArray(CArray<PContact, PContact>& arContact, CArchive& ar)
{
      CObject::Serialize(ar);
      if (ar.IsStoring())
      {
            ar.WriteCount(arContact.GetSize());
      }
      else
      {
            DWORD nOldSize = ar.ReadCount();
            arContact.SetSize(nOldSize, -1);
      }
for (int i = 0; i < arContact.GetSize(); i++)
{
// serealize items in the array
}
}
0
 
migelCommented:
ooops CObject::Serealize must be deleted!
0
 
RMD010799Author Commented:
Hmmm.... how would I go about serializing the items in the array so that I can retreive them simple by retreiving the array in which there are stored. How do I make it so that the CString objects are happy is what I am trying to say...
0
 
migelCommented:
for (int i = 0; i < arContact.GetSize(); i++)
      {
      // serealize items in the array
     PContact cont = arContact[i];
     //MFC provide function to serialize CString object
    // void AFXAPI SerializeElements(CArchive& ar, CString* pElements, int nCount);
      SerializeElements(ar, &PContact.str1, 1);
      SerializeElements(ar, &PContact.str2, 1);
// and so on...
    if (!ar.IsStoring())
       arContact.SetAt(i, cont);
      }
0
 
Answers2000Commented:
I serialize arrays using my own code,  here's example :

1. Incorporate these 2 functions in a header (e.g. stdafx.h)

template< class ARRAY, class ITEM >
void SerializeArray(CArchive& ar, ARRAY& rArray )
{
      if ( ar.IsStoring() )
      {
            ar << (int)1000 ; // version

            int nCount = rArray.GetSize() ;
            ar << nCount ;

            if ( nCount > 0 )
            {
                  for ( int ii = 0 ; ii < nCount ; ii++ )
                  {
                        ar << rArray[ii] ;
                  }
            }
      }

      else
      {
            int nVersion ;
            ar >> nVersion ;
            ASSERT( nVersion == 1000 ) ;

            rArray.RemoveAll() ;

            int nCount ;
            ar >> nCount ;

            if ( nCount > 0 )
            {
                  for ( int ii = 0 ; ii < nCount ; ii++ )
                  {
                        ITEM str ;
                        ar >> str ;
                        rArray.Add( str ) ;
                  }
            }
      }

}

template< class ARRAY, class ITEM >
void SerializeArray_Serialize(CArchive& ar, ARRAY& rArray )
{
      if ( ar.IsStoring() )
      {
            ar << (int)1000 ; // version

            int nCount = rArray.GetSize() ;
            ar << nCount ;

            if ( nCount > 0 )
            {
                  for ( int ii = 0 ; ii < nCount ; ii++ )
                  {
                        rArray[ii].Serialize( ar ) ;
                  }
            }
      }

      else
      {
            int nVersion ;
            ar >> nVersion ;
            ASSERT( nVersion == 1000 ) ;

            rArray.RemoveAll() ;

            int nCount ;
            ar >> nCount ;

            if ( nCount > 0 )
            {
                  for ( int ii = 0 ; ii < nCount ; ii++ )
                  {
                        ITEM str ;
                        str.Serialize( ar ) ;
                        rArray.Add( str ) ;
                  }
            }
      }

}


2. You can use SerializeArray function to serialize an array where the << and >> operators exist (e.g. CString) for the elements.  For example if your document contains

a m_arrayString defined as CArray<CString,CString&>

void CMailGuruDoc::Serialize(CArchive& ar)
{
      CDocument::Serialize(ar) ;

      if (ar.IsStoring())
      {
      SerializeArray< CArray<CString,CString&>, CString >( ar, m_arrayString ) ;
              } else
      {
      SerializeArray< CArray<CString,CString&>, CString >( ar, m_arrayString ) ;
              }
}


3. You can SerializeArray_Serialize if the array elements are you own class (which has the serialization methods defined)



There are shorter ways to do this, but using your own code gives you _exact_ control.        

0
 
RMD010799Author Commented:
Thanks for all u'r help guys.
0
 
lipanshiCommented:
you may use' for' cycle .because you know array that count cycle number
0
 
RMD010799Author Commented:
Migel's example on how to serialize my array was in-fact the best answer. I wish I could give you points for it... perhaps I can. How would I go about retreiving the array that I serialize with your method from the file? I am unclear how you method saves that data... so I am unclear on how to retreive it. Thanks for your help. If you would like... I can post a new question and offer you points...
0
 
RMD010799Author Commented:
Also... to add to my above comment... I the code that Migel gave me, I get an "illegal use of this type" error on these lines:

SerializeElements(ar, &PContact.sEMail, 1);
SerializeElements(ar, &PContact.sIP, 1);
SerializeElements(ar, &PContact.sNick, 1);

PContact is a struct with three CStrings... sEMail, sIp and sNick.
0
 
RMD010799Author Commented:
Please disregard the latest post... I figured it all out. Thanks for your help... consider this question forum closed.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now