2016-09-22 23 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