0

I have the following struct

typedef struct a_t
{
    vector <int> a;
    int p;
}a;

typedef struct b_t
{
    a x;
    int y;
}b;

struct a is a struct contain a vector,struct b contain struct a I wanna write/read the struct b into a binary file. The following code doesn't work

int main()
{

    b m;
    m.x.a.push_back(1);
    m.x.a.push_back(2);
    m.x.a.push_back(3);
    m.x.p = 5;
    m.y = 7;
    cout << sizeof(m.y) << endl;
    cout << sizeof(m.x) << endl;
    cout << sizeof(m) << endl;
    ofstream outfile("model",ios::out|ios::binary);
    outfile.write((char*)&m,sizeof(m));
    outfile.close();


    b p;
    ifstream iffile("model", ios::in|ios::binary);
    iffile.read((char*)&p,sizeof(a));
    iffile.close();

    cout << p.y << endl;;
    cout << p.x.p << endl;
    cout << p.x.a[0] << endl;
    cout << p.x.a[1] << endl;
    cout << p.x.a[2] << endl;
    return 0;
}

The error message is "* glibc detected double free or corruption (top): 0x0000000000504010 ** Aborted (core dumped)" beside,it does't write the struct into the file.

1
  • 1
    Where possible, prefer std::array to std::vector. std::vector manages dynamically allocated memory, while std::array doesn't. In this case, it would make the naive method of accomplishing this (cast to/from char* and write/read) work. Commented Aug 26, 2016 at 22:56

1 Answer 1

1

You cannot write and read vectors because they allocate data on the heap. If you have real limits in your application you may decide it's better (for speed and clarity, potentially sacrificing storage) to use a normal C array:

#define MAXARR_A 100

typedef struct a_t
{
    int a[MAXARR_A];
    int p;
} a;

Otherwise you have to serialise your vector by writing out a size and then dumping the array data. To read it back in you read the size, then resize the vector and read the bytes into it.

Edit: Decided to add some code for you... It might compile! =)

void write_a( a& data, ostream& s )
{
    size_t len = data.a.size();
    s.write( (char*)&len, sizeof(len) );
    s.write( (char*)&data.a[0], len * sizeof(int) );
    s.write( (char*)&data.p, sizeof(int) );
}

void write_b( b& data, ostream& s )
{
    write_a( data.x, s );
    s.write( (char*)&data.y, sizeof(int) );
}

void read_a( a& data, istream& s )
{
    size_t len;
    s.read( (char*)&len, sizeof(len) );
    data.a.resize(len);
    s.read( (char*)&data.a[0], len * sizeof(int) );
    s.read( (char*)&data.p, sizeof(int) );
}

void read_b( b& data, istream& s )
{
    read_a( data.x, s );
    s.read( (char*)&data.y, sizeof(int) );
}

Note that I haven't included any error checking... Also, it would be more C++-like to make these functions as read and write member functions on the structures.

Sign up to request clarification or add additional context in comments.

3 Comments

actually,i indeed need to write a vector into the file.
Yeah, so that's what all the extra code in my edit is about. You can't just dump the vector. It's a class whose internals are pointing to memory. If you just write it out, you will be writing the pointers, not the data they point to. When you read those pointers back in they no longer point to valid memory. And then, when the vector goes out of scope you get that error message because the vector is freeing memory that it didn't request. My solution serialises the vector's contents out, including a size value so you know how many elements to read back in.
Just to be clear, the first block of code in my answer is an alternative... The second block of code in my answer is how you need to do it if you want to use vectors.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.