我正在尝试创建一个存储员工数据库的程序,并将它们存储在外部文件中。从.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.
}
答案 0 :(得分:3)
您尚未向我们展示mEmployees
的声明,但我认为它是某种std::vector
。问题是您尝试将文件读入vector
对象,而不是其内容。这会破坏vector
以及它旁边的任何其他内存,从而导致崩溃。
你可能想要的是:
empIn.read((char*)&mEmployees[0], size2);
或 C ++ 11 :
empIn.read((char*)mEmployees.data(), size2);
实际将文件的内容读入vector
的内容。
要理解为什么会发生这种情况,您应该知道vector
的内容未存储在vector
本身中(他们怎么可能?大小是动态的)。相反,vector
的常见实现具有指向存储区域的开始和结束的指针,存储区域中的某个位置,实际存储内容。当您尝试将文件读入vector
的内存布局时,您将覆盖这些指针,以及超出vector
本身的内存,从而破坏该向量。
答案 1 :(得分:0)
转换为(char*)
告诉编译器放弃它通常会做的类型检查。由于ifstream
要求您传递char*
,因此必须在此情况下执行投射。问题是,这reinterpret_cast
是一个相当钝的工具,如果您打算从vector<Employee>*
进行转换,则无法提醒您正在转换Employee*
。
请记住,像这样的演员是低级操作,其目的是告诉编译器“你知道你在做什么,即使它看起来是错误的”。应该特别小心使用它们。
您正在做的更好,更正的表格将是:
empIn.read( reinterpret_cast<char*>(&mEmployees[0]), mEmployees.size() );