【问题标题】:Program crashing when trying to read a vector of objects尝试读取对象向量时程序崩溃
【发布时间】:2013-08-29 15:49:05
【问题描述】:

我有下面的类,它有一个vector of objects。当我使用类对象读取向量的值时,程序崩溃了。我什至尝试输入一个try block,但控制没有进入@ 987654323@.

这本书类:

class Book
{
    public:
        char isbn[11];
        char name[50];
        char author_name[50];
        char pub_name[50];
        char edition[10];
        float cost;
        char dept[10];
        int  count;
        char id[8];

};

这是 Library 类,其中包含 vector of class Book

class Library
{
    public:
        char l_name[50];
        char admin_name[50];
        int phone_no;
        char location[50];
        vector<Book> v;
};

这是主要功能

int main()
{

    Library lib; //LIBRARY OBJECT
    Book b; //BOOK OBJECT

        fstream fp("library1.bin",ios::in | ios::binary); //OPEN FILE IN READ MODE
        if(!fp) cout<<"reading failed...";
        try
        {

        fp.read(reinterpret_cast<char *>(&lib),sizeof(lib)); //READ LIBRARY DETAILS
        if(fp.bad() == true) cout<<"Read failure..."<<endl;
        fp.close();

        cout<<"Enter ISBN number:"; cin>>b.isbn; //READ ISDN NUMBER FROM USER



            for(int i=0;i<lib.v.size();i++) //CHECK WHETHER BOOK ALREADY EXISTS
            {
                Book b1 = lib.v[i];
                if(strcmp(b1.isbn,b.isbn) == 0)
                {
                    lib.v[i].count++;
                }
            }
      } 
      catch(exception& e) //CATCH ANY EXCEPTIONS
      {
        cout<<"Error:"<<e.what()<<endl;
      }
      catch(...) //CATCH ANY UNCAUGHT EXCEPTIONS
      {
        cout<<"Unknown error occured:";
      }
}

当我尝试检查 ISDN 号码时,程序崩溃了。

【问题讨论】:

  • 解释你所说的“程序崩溃”是什么意思。你有没有附加调试器?
  • 另外,你为什么用std::vector而不是std::string
  • 由于这是标记为 C++,请停止使用 C 字符串并改用 std::string
  • 没有必要全大写的 cmets。
  • @ManojKumar:如果你的学校教你直接从磁盘读取复杂的数据结构作为字节流,不考虑填充、对齐或字节序,或者教你使用char[]而不是@ 987654332@,或者教你不要把引用当别名,或者教你在接受用户输入的时候不要检查错误……那我建议你转学!

标签: c++ stl stdvector


【解决方案1】:

包含vector 基础数据的内存不存储在vector 类本身中,只存储了指向它的指针。

因此,当您执行fstream::read 时,您将使用指向内存中某个随机位置的指针初始化此vector(您编写它时vector 数据所在的位置,这可能无法访问或数据早已不复存在,除非您在程序的当前运行期间编写了它并且 vector 仍在范围内),因此任何访问数据的尝试都将导致未定义的行为。

我建议您不要尝试直接使用 fstream::read 恢复您的课程,因为让它工作可能有点困难(更不用说随之而来的许多可能的问题),而是写/读成员一一对应文件。

【讨论】:

    【解决方案2】:

    您的示例中可能缺少一些代码,但我怀疑问题是您在向量上使用[] 而不使用大小构造函数resizepush_back 来实际增加向量的大小.

    【讨论】:

      【解决方案3】:

      您不能使用istream::read 来读取向量,您必须使用循环并单独读取每个向量项。

      出于同样的原因,您不应该使用ostream::write 来编写向量。虽然它可以在不崩溃的情况下工作,但它不会向文件写入任何有用的东西。同样,您应该使用循环单独写入向量中的每个项目。先写下向量的大小可能也很有帮助,所以当你读回它时,你就会知道向量中有多少项。

      换句话说,C++ 中的二进制 I/O 并不像您想象的那么简单。你还有一些工作要做。

      【讨论】:

        猜你喜欢
        • 2021-01-08
        • 2017-02-08
        • 2014-06-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多