Alex Oiko
Alex Oiko

Reputation: 3

double free or corruption error when using fread in c++

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

Answers (3)

JP Cordova
JP Cordova

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

maditya
maditya

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

reima
reima

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

Related Questions