1

I am trying to make a program that stores a database of employees and stores them in an external file. the function that reads a vector from the .dat file and loads it into the program reads the file but whenever I try to display or modify the loaded vector the program crashes.

//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. } 
1
  • Are you by any change introducing the same bug in the code that writes the data? Note that any data you have written so far with the bugged code would be unusable (as you would have actually written a bunch of random bytes) Commented Dec 26, 2012 at 4:11

2 Answers 2

3

You haven't showed us your declaration of mEmployees, but I assume its a std::vector of some kind. The problem is that you are trying to read the file into the vector object, instead of into its content. That will corrupt the vector, as well as any other memory next to it, causing crashes further on.

What you probably want instead is:

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

or in C++11:

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

to actually read the contents of the file into the contents of the vector.

To understand why this is happening, you should know that the contents of a vector are not stored within the vector itself (how could they? the size is dynamic). Instead, a common implementation of vector has pointers to the begin and end of a storage area, somewhere in the free store, where the contents are actually held. When you try to read a file into the memory layout of the vector you are overwriting those pointers, as well as memory beyond the vector itself, corrupting the vector among other things.

Sign up to request clarification or add additional context in comments.

Comments

0

The cast to (char*) tells the compiler to discard the type-checking that it would normally do. It is necessary to perform the cast in this case since ifstream requires you to pass a char*. The problem is, this reinterpret_cast is a rather blunt instrument and fails to warn you that you are converting from a vector<Employee>* when you intended to convert from an Employee*.

Just remember that casts like this are low-level operations whose purpose is to tell the compiler that "you know what you are doing, even though it seems wrong". They should be used with extra care.

A better, and corrected, form for what you are doing would be:

empIn.read( reinterpret_cast<char*>(&mEmployees[0]), mEmployees.size() ); 

2 Comments

i tried this and it stopped my program from crashing but when i called the function to display the contents of the vector it only displayed a random bunch of characters.
@aceassasin: You haven't shown the code which attempts to show the contents. Normally, this would have to display the contents of mEmployee one field at a time and one record at a time.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.