• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 505
  • 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
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
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

Featured Post

[Webinar] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

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