在我的简单c ++代码中访问违规写入位置

时间:2012-12-10 18:43:14

标签: c++

这是我的代码:

#include <iostream>
#include <fstream>
#include <string>


using namespace std;

struct car
{
    string name, model;
    int year;   
};

void search_car(int CarYear)
{
    cout<<"1";
    ifstream in;
    cout<<"2";
    car c1;
    cout<<"3";
    in.open("Cars.txt",ios::binary|ios::in);
    cout<<"4"<<endl;
    while(!in.eof())
    {
        cout<<" 5";
        in.read((char *) &c1, sizeof(car));
        cout<<" 6.Car Year: "<<c1.year<<endl;
        if(c1.year == CarYear)
        {
            cout<<" 7>>> ";
            cout<<c1.name<<" "<<c1.model<<" "<<c1.year;
            cout<<" <<<8"<<endl;
        }
    }
    cout<<" 9";
    in.close();
    cout<<" 10";    
}

void main()
{
    car c[100];
    int carNum, menuAct = 0, CarYear = -1, cycle = 1;
    ofstream out;
    while (cycle == 1)
    {
        //clrscr();
        cout<<endl<<endl<<"1.Enter New car"<<endl<<"2.Search"<<endl<<"3.Exit"<<endl;
        cin>>menuAct;
        cout<<"   Menu Action: "<<menuAct<<endl;
        if(menuAct == 1)
        {
            cout<<"Enter Num OF Cars: ";
            cin>>carNum;
            out.open("Cars.txt",ios::binary|ios::out|ios::app);
            for(int i = 0; i < carNum; i++)
            {
                cout<<"Enter Name OF Car: ";
                cin>>c[i].name;
                cout<<"Enter model OF Car: ";
                cin>>c[i].model;
                cout<<"Enter year OF Car: ";
                cin>>c[i].year;     
                out.write((char *) &c[i], sizeof(car));
            }
            out.close();
        }
        else if(menuAct == 2)
        {
            cout<<"Enter Car Year: ";
            cin>>CarYear;
            cout<<" 0";
            //cout<<" Y: "<<CarYear;
            search_car(CarYear);
            cout<<" 11";
            //menuAct = 0;
        }
        else if(menuAct == 3)
        {
            cycle = 0;
        }
    }   
}

错误:

http://s3.picofile.com/file/7580464836/cpp_err11.jpg

发生了什么事? 我用了一些cout来追踪发生了什么,代码在10号停止了。

最后一辆车也打印了两次!!!

1 个答案:

答案 0 :(得分:2)

我对你遇到问题并不感到惊讶!你从字面上保存结构的字节,然后当你从文件中读回它们时,你希望你再次得到一个std :: string。它根本不起作用。

问题是car结构不包含它引用的所有数据:std :: string成员实际上只是指向包含实际字符串数据的动态数组的指针。您将汽车结构写为原始字节,因此字符串永远不会归档。他们无法从中读回来。

更糟糕的是,当您重新读取结构时,您将std :: string中的指针设置为垃圾值。你不可能希望他们碰巧指出的记忆包含你想要的东西。

您需要为car结构定义序列化函数,使用深层副本将其发送到outstream,并安全地将其读回。切勿将原始指针值写入文件。

示例代码

ostream& operator <<(ostream& os, const car& c) {
    return os << c.name << endl << c.model << endl << c.year << endl;
}
istream& operator >>(istream& is, car& c) {
    is >> c.name;
    is >> c.model;
    is >> c.year;
    return is;
}

in.read((char *) &c1, sizeof(car));更改为in >> c1;

out.write((char *) &c[i], sizeof(car));更改为out << c[i];

更整洁! PS。作为一个很好的一般规则,在你理解它的作用以及如何处理字符串之前,不要强制转换为char*