CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Sep 2008
    Posts
    2

    Binary IO with Objects and Vectors

    I'm getting weird run-time errors from Netbeans with the following code:

    Code:
    #include <fstream>
    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    class Data {
        private:
            double value;
            vector<int> listOfInts;
        public:
            Data(double);
            void Insert(int);
            void ShowVector();
            double GetValue(){ return value; }
    };
        
    Data::Data(double v)
    {
        value = v;
    }
    
    void Data::Insert(int i)
    {
        listOfInts.push_back(i);
    }
    
    void Data::ShowVector()
    {
        vector<int>::iterator it;
        for(it = listOfInts.begin(); it != listOfInts.end(); it++){
            cout << (*it);
        }
        cout << endl;
    }
        
    bool load(Data *d)
    {
        ifstream fin("test.bin", ios_base::in | ios_base::binary);
        if (!fin.is_open()){ return false; }
        
        fin.read((char*)(d), sizeof(Data));
        fin.close();
        return true;
    }
    
    bool save(Data *d)
    {
        ofstream fout("test.bin", ios_base::out | ios_base::binary | ios_base::trunc);
        if (!fout.is_open()){ return false; }
        
        fout.write((const char*)(d), sizeof(Data));
        fout.close();
        return true;
    }
    
    int main() {
        Data x(4.5);
        Data *y = new Data(7.8);
    
        cout << x.GetValue() << endl;
        x.Insert(1);
        x.Insert(2);
        x.Insert(3);
        x.Insert(4);
        save(&x);
    
        cout << y->GetValue() << endl << "Vector : ";
        y->ShowVector();
        load(y);
    
        cout << y->GetValue() << endl << "Vector : ";
        y->ShowVector();
        
        delete y;
        return 0;
    }
    /cygdrive/d/Program Files/NetBeans 6.1/cnd2/bin/dorun.sh: line 103: 2132 Aborted (core dumped) "$pgm" "$@"

    My actual project (far too much code to post here), which uses several vectors, one of which is of pointers to abstract classes, complains even more at run-time with the following:

    handle_exceptions: Error while dumping state (probably corrupted stack)
    /cygdrive/d/Program Files/NetBeans 6.1/cnd2/bin/dorun.sh: line 103: 2128 Segmentation fault (core dumped) "$pgm" "$@"

    Is this a cygwin issue, my OS (Win2k) or something code related?

  2. #2
    Join Date
    Dec 2004
    Location
    Poland
    Posts
    1,165

    Re: Binary IO with Objects and Vectors

    Serializing vector in this manner does not let you store elements contained by it. All you do is writing an internal pointer to elements, and when you load an object from a file, you load this pointer value, which may lead anywhere into memory, but very unlikely into place where elements are stored. you need to serialize/deserialize contents of vector manually, or use some other solutions, like Boost.Serialization.

    Cheers
    B+!
    'There is no cat' - A. Einstein

    Use &#91;code] [/code] tags!

    Did YOU share your photo with us at CG Members photo gallery ?

  3. #3
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Binary IO with Objects and Vectors

    Quote Originally Posted by Ceramic Weasel
    I'm getting weird run-time errors from Netbeans with the following code:
    As Hobson pointed out, you do not write serialized data this way.

    If you take a look at the file you are writing in a binary editor, do you see any of your data there? Of course not, all you see mostly is junk. So don't expect things to correctly happen when trying to read back junk data. Garbage in, garbage out (or in this case, garbage out, garbage in).

    The proper way to store items is to actually store the item. If it's a string, the whole string must be stored, if it's an object that contains a person's name and address, then the name and address must be stored, etc. You can't do that by storing meaningless pointer values. To do this, you must use proper object serialization.

    Regards,

    Paul McKenzie

  4. #4
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: Binary IO with Objects and Vectors

    ios_base::binary can be quite confusing and I know I was caught out at first. I also expected that if I set the stream to binary it would put the numbers in in a binary format. I also thought the API was bad because it didn't support binary streaming.

    Now whilst it may be true that being able to stream numbers in binary format then read them back in the same format can be useful, the same isn't true for whole objects. Not even POD structs unless you can be certain that the alignment will match. Even for numbers there can be endian issues across platforms (although an API might support a single endian streaming variety).

    If you stream pointers into a file these values are useful only during the lifetime of the pointer in memory. Now it's not totally useless as you may be using a file as temporary storage during the program lifetime, but the file will be pretty useless once the program terminates (or the memory is freed).

    Objects like std::vector will contain pointers and writing them byte-by-byte into a file then reading them back will be useless.

    The way to write one of these is either:
    - Using delimited text
    or
    - Writing a header section followed by a sequence of records.

    Delimited text, for most purposes, can be the simpler to code, although the header and binary sequence of records could be both faster and more compact in file-space use.

  5. #5
    Join Date
    Sep 2008
    Posts
    2

    Re: Binary IO with Objects and Vectors

    Quote Originally Posted by NMTop40
    The way to write one of these is either:
    - Using delimited text
    or
    - Writing a header section followed by a sequence of records.

    Delimited text, for most purposes, can be the simpler to code, although the header and binary sequence of records could be both faster and more compact in file-space use.
    Gah, so what's the best way to do this with a vector of pointers to abstract objects? I'd need to output some sort of typeid for each one so I know what I'm looking at before reading it back in.

  6. #6
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Binary IO with Objects and Vectors

    Yup, that's more or less it.

    A tip: If you use only a single byte to distinguish between several different derived types of a single base class, you can use fungetc() or the iostream equivalent to put that byte back in the stream after you read it. The unget functionality is only guaranteed to work for one byte, though.

    The advantage here is that each derived type can have a complete read() function which always works regardless of what's called before; *and* a higher-level read() function can peek ahead to see which of the derived types' read() functions to call next, simultaneously.

  7. #7
    Join Date
    Apr 2007
    Location
    Mars NASA Station
    Posts
    1,436

    Re: Binary IO with Objects and Vectors

    How to serialize in C++.

    I looking for non-binary data type first then binary.

    Thanks for your help.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured