Reputation: 3
So basically I was writing a test program to see if I could write and read a vector of queues into a binary file using fwrite and fread respectively. Even though the reading and writing part is done correctly and the values are correct, I get a double free or corruption error. The test code is the following
#include <stdio.h>
#include <vector>
#include <queue>
int main(){
vector<queue<unsigned> > hello(17);
vector<queue<unsigned> > here(17);
queue<unsigned> temp;
for(int f=0;f<4;f++){//initialise a random queue
temp.push(f);
}
for(int i=0;i<hello.size();i++){//assign random queue to every index of vector
hello[i]= temp;
}
FILE *fo;
fo = fopen("hello","wb");
fwrite(&hello[0],sizeof(queue<unsigned>),hello.size(),fo);
fclose(fo);
printf("Writing done!\n");
FILE *fi;
fi=fopen("hello","rb");
fread(&here[0],sizeof(queue<unsigned>),here.size(),fi);
fclose(fi);
printf("Reading done!\n");
for(int i=0;i<here.size();i++){
printf("At key %d value at front is is %d",i,here[i].front());
here[i].pop();
printf(" value %d ",here[i].front());
here[i].pop();
printf(" value %d\n",here[i].front());
}
}
The error seems to be when doing the fread operation.
Upvotes: 0
Views: 724
Reputation: 119
You are copying queues as if they where contiguous in memory, and they aren't. Using fwrite, you must copy element by element, because as @reima said, at background you are using memcpy.
Best regards.
Upvotes: 0
Reputation: 8886
fread and fwrite take a raw pointer as their first argument. In each case, what you've passed in is the address of a queue (the first element in the vector of queues named hello
and the first element of the vector of queues named here
.
What you are writing is the actual queue classes themselves, i.e. the class that contains the queue of elements you want to write. Depending on the implementation of queue, you could be writing anything (or not!). For example, if the queue class contains a pointer pointing to an array of elements, you are writing the value of a pointer, but not the elements themselves.
I would recommend serializing (Is it possible to serialize and deserialize a class in C++?) and deserializing your vector of queues.
Upvotes: 1
Reputation: 2126
What you are doing is essentially equivalent to
memcpy(&here[0], &hello[0], sizeof(queue<unsigned>)*here.size());
So you are making a (shallow) copy of the internal representation of the queues, which includes some pointers. In the destructors of the queues, both the original and the copy try to free the same area of memory. This results in the double free.
The bottom line is: you can't just do a plain shallow memcpy
of structures which store pointers and expect it to work.
Upvotes: 1