【问题标题】:double free or corruption error when using fread in c++在 C++ 中使用 fread 时出现双重释放或损坏错误
【发布时间】:2013-03-30 12:04:52
【问题描述】:

所以基本上我正在编写一个测试程序,看看我是否可以分别使用 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 操作时。

【问题讨论】:

  • 您可能正在写出指向磁盘的指针,然后将它们读回,而系统不喜欢这样。如果你的结构包含指针,你不能简单地将它们写入磁盘并再次读回它们;您需要对结构进行“线性化”或“序列化”,然后在输入时对它们进行去线性化或反序列化,注意进行适当的分配。这比只使用fread()fwrite() 要难得多。

标签: c++ fwrite fread


【解决方案1】:

fread 和 fwrite 将原始指针作为它们的第一个参数。在每种情况下,您传入的是队列的地址(队列向量中名为hello 的第一个元素和队列向量中名为here 的第一个元素。

您正在编写的是实际的队列类本身,即包含您要编写的元素队列的类。根据队列的实现,你可以写任何东西(或者不写!)。例如,如果队列类包含一个指向元素数组的指针,那么您写入的是指针的值,而不是元素本身。

我建议序列化 (Is it possible to serialize and deserialize a class in C++?) 并反序列化您的队列向量。

【讨论】:

    【解决方案2】:

    你所做的基本上等同于

    memcpy(&here[0], &hello[0], sizeof(queue<unsigned>)*here.size());
    

    因此,您正在制作队列内部表示的(浅)副本,其中包括一些指针。在队列的析构函数中,原始和副本都试图释放相同的内存区域。这导致双重释放。

    底线是:你不能只做一个简单的浅memcpy 结构来存储指针并期望它工作。

    【讨论】:

      【解决方案3】:

      您正在复制队列,就好像它们在内存中是连续的,但它们不是。使用 fwrite,您必须逐个复制元素,因为正如@reima 所说,在后台您使用的是 memcpy

      最好的问候。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多