1

我正在尝试制作一个程序来存储员工数据库并将它们存储在外部文件中。从 .dat 文件中读取向量并将其加载到程序中的函数会读取该文件,但每当我尝试显示或修改加载的向量时,程序就会崩溃。

//displays vector
void Database:: displayAll() const
{
    for(std::vector<Employee>::const_iterator iter = mEmployees.begin(); iter != mEmployees.end(); ++iter)
    {
        iter -> display();
    }

}

std::vector<Employee> mEmployees;

void Database::readData()
{
    ifstream empIn("employee.dat" , ios::binary);
    empIn.seekg(0,ifstream::end);
    long size2 = empIn.tellg();
    empIn.seekg(0,ifstream::beg);
    mEmployees.resize(size2);
    empIn.read((char*)&mEmployees, size2);
    empIn.close();
    cout << mEmployees.size() << endl; //this tests whether or not it reads.
}
4

2 回答 2

3

你没有向我们展示你的声明mEmployees,但我认为它是std::vector某种形式的。问题是您试图将文件读入vector对象,而不是其内容。这将损坏vector以及它旁边的任何其他内存,从而导致进一步崩溃。

您可能想要的是:

empIn.read((char*)&mEmployees[0], size2);

或在C++11中:

empIn.read((char*)mEmployees.data(), size2);

真正将文件的内容vector.

要了解为什么会发生这种情况,您应该知道a的内容vector不存储在其vector自身中(它们怎么可能?大小是动态的)。相反,一个常见的实现vector有指向存储区域开始和结束的指针,在空闲存储的某个地方,内容实际保存在那里。当您尝试将文件读入内存布局时,vector您将覆盖这些指针以及超出vector自身的内存,从而破坏向量等。

于 2012-12-26T03:16:16.413 回答
0

强制转换(char*)告诉编译器放弃它通常会进行的类型检查。在这种情况下有必要执行强制转换,因为ifstream需要您通过char*. 问题是,这reinterpret_cast是一个相当生硬的工具,vector<Employee>*当您打算从Employee*.

请记住,像这样的强制转换是低级操作,其目的是告诉编译器“你知道自己在做什么,即使它看起来是错误的”。使用时应格外小心。

对于您正在做的事情,一个更好且更正的表格是:

empIn.read( reinterpret_cast<char*>(&mEmployees[0]), mEmployees.size() );
于 2012-12-26T03:34:47.343 回答