2016-09-22 22 views
-4
#include<iostream> 
#include<string> 
#include<fstream> 
using namespace std; 
class telephone 
{ 
    string name; 
    long number; 
    public : 
    void getdata(); 
    void display(); 
}; 
void telephone :: getdata() 
{ 
    cout<<"Enter the name : "; 
    getline(cin,name); 
    cout<<"Enter the number : "; 
    cin>>number; 
} 
void telephone :: display() 
{ 
    cout<<"1. Name : "<<name<<endl; 
    cout<<"2. Number : "<<number<<endl; 
} 
int main() 
{ 
    fstream f; 
    telephone p,q; 
    f.open("dir.txt",ios::out); 
    p.getdata(); 
    f.write((char*)&p,sizeof(telephone)); 
    f.close(); 
    f.open("dir.txt",ios::in); 
    while(f.read((char*)&q,sizeof(telephone))) 
    { 
    q.display(); 
    } 
    f.close(); 
    return 0; 
} 

我已经写了这段代码来写入和读取类object.be上的文件的数据。它显示输出但显示一些错误。C++将数据拷贝到类对象的文件处理

OUTPUT:

Enter the name : rahul 
Enter the number : 234546 
1. Name : rahul 
2. Number : 234546 
*** Error in `./a.out': double free or corruption (fasttop): 0x08f861a8 *** 
Aborted (core dumped) 

我以文件扩展比如后缀名为.txt,.bin和.DAT,但它显示了同样的error.Please帮我消除这种误差尝试。

+2

如果您使用C++,请使用'ifstream','ofstream'和''<<' and '>>'操作符。 – AndyG

+2

您需要序列化,因为有一个字符串作为对象 – Raindrop7

+2

[C++读取和写入同一类的多个对象]的可能重复(http://stackoverflow.com/questions/18186701/c-read-and-write-multiple-objects同类) – Raindrop7

回答

1

telephone作为二进制blob写入文件将不起作用。 telephone包含name,并且名称是std::string。 A std::string通常不包含它表示的字符串数据;它包含一个指向字符串数据的指针。

所以,当你

f.write((char*)&p,sizeof(telephone)); 

你真正写入到文件是不是字符串数据,而是指向字符串数据。这意味着,

f.read((char*)&q,sizeof(telephone)); 

读回p的指针q,这意味着,pq两个点在相同的字符串数据。这不好。

pq走出去的范围和被破坏,他们摧毁name,并name,是个不错的小std::string,并释放它指向的内存。这使得包含std::string的另一个对象指向已释放的内存,迟早会使用其他对象并调用undefined behaviour或被销毁并尝试释放先前释放的内存。这是错误消息中的“double free”意思。相同的内存已被释放两次。

在你的情况,如果q被删除之前pq释放内存,无论p及留p在一个无效的内存位置指示q点。几纳秒后,p被删除,p无法释放已经释放的内存。

要解决此问题,您必须确保将std::string的内容写入文件,然后回读。这被称为serialization

对这个问题的典型解决方案是与<<将数据写入一个文本格式的文件,并与>>读回(这可能需要你来实现<<>>运营商类)

class telephone 
{ 
    string name; 
    long number; 
    public : 
    void getdata(); 
    void display(); 
    friend std::istream & operator<<(std::istream & out, const telephone & tp); 
    friend std::ostream & operator>>(std::ostream & in, telephone & tp); 
}; 

或添加序列化功能的类

class telephone 
{ 
    string name; 
    long number; 
    public : 
    void getdata(); 
    void display(); 
    bool serialize(std::iostream & out); 
    bool deserialize(std::iostream & in); 
}; 

这些功能的文字可能是这个任务的点,所以我会在这里停止。别担心。如果你遇到麻烦,两种方法都有非常好的在线记录。我建议从第一个选项开始。调试起来要容易得多,因为您可以阅读文本文件以查看是否出错。

+0

谢谢。但是如何编写超载运算符函数的定义。 –

+0

基本骨架和思想在这里覆盖:http://stackoverflow.com/questions/4421706/operator-overloading。我不会涵盖的功能的内涵,但基本上是一堆像'in >> phone.name'这样的东西 – user4581301