所以基本上我正在编写一个测试程序,看看我是否可以分别使用fwrite和fread将一个队列向量写入二进制文件。即使读写部分正确完成且值正确,我也会遇到双重释放或损坏错误。测试代码如下
#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());
}
}
执行fread操作时似乎是错误。
答案 0 :(得分:1)
fread和fwrite将原始指针作为第一个参数。在每种情况下,您传入的是队列的地址(名为hello
的队列向量中的第一个元素以及名为here
的队列向量的第一个元素。
您所编写的是实际的队列类本身,即包含您要编写的元素队列的类。根据队列的实现,你可以写任何东西(或不!)。例如,如果队列类包含指向元素数组的指针,则表示您正在编写指针的值,而不是元素本身。
我建议序列化(Is it possible to serialize and deserialize a class in C++?)并反序列化您的队列向量。
答案 1 :(得分:1)
你在做什么基本上等同于
memcpy(&here[0], &hello[0], sizeof(queue<unsigned>)*here.size());
因此,您正在制作队列内部表示的(浅)副本,其中包括一些指针。在队列的析构函数中,原始版本和副本都试图释放相同的内存区域。这导致双重免费。
底线是:你不能只做一个简单的浅memcpy
结构来存储指针并期望它能够工作。
答案 2 :(得分:0)
您正在复制队列,就好像它们在内存中是连续的一样,但它们不是。使用fwrite,必须逐个元素地复制,因为正如@reima所说,在背景中你正在使用 memcpy 。
最好的问候。