1

I think I am writing incorrectly to my binary file. We are supposed to create a program that lets us add our college courses to a list with details like grade, units, etc. We're also supposed to double the array capacity whenever we add an item to our array (hence the function doubleArrayCapacity)

  void doubleArrayCapacity(Course*&, int&, int);

  ...

  int cap = 2;
  int size = 0;
  Course* courses = new Course[cap];

  fstream fin;
  fin.open("myCollegeCourses.9.bat", ios::binary|ios::in);
  if (fin.good())
  {
    fin.read(reinterpret_cast<char*>(&size), sizeof(size));
    doubleArrayCapacity(courses, cap, size);
    fin.read(reinterpret_cast<char*>(courses), cap * sizeof(Course));
  }
  fin.close();

  ...

  fstream fout;
  fout.open("myCollegeCourses.9.bat", ios::binary|ios::out);
  fout.write(reinterpret_cast<char*>(&size), sizeof(size));
  fout.write(reinterpret_cast<char*>(courses), cap * sizeof(Course));
  fout.close();

  ...

  void doubleArrayCapacity(Course*& array, int& capacity, int newCapacity)
  {
    Course* temp = new Course[2 * capacity];
    for (int i = 0; i < capacity; i++)
      temp[i] = array[i];
    delete [ ] array;
    array = temp;
    capacity = newCapacity * 2;
  }

If I add 4 items to my array, the program works fine. Once I get to 5 objects, errors occur. The file is not read back correctly and the 5th item is read as null or zeros. I think I am not correctly outputting my data to my binary file. Can anyone see what I'm doing wrong?

2
  • Normally you would only double the capacity, when the new entry does not fit within the existing capacity, not each time you add an entry. Doubling the size each time will effectively insert uninitialized data into your array. Commented Oct 27, 2016 at 7:32
  • BTW: Writing out this data as is to disk is not portable at all across different platforms as numbers may have different representations (big vs. little endian) and alignment of data types may have different requirements leading to different padding in the struct. Commented Oct 27, 2016 at 7:34

2 Answers 2

1

As I can see, you have 2 potential problems here

  1. First problem is in the serialization, fout.write(reinterpret_cast<char*>(courses), cap * sizeof(Course)); the correctness of the serialization depends on the internal layout and alignment of the data members of the Course object.
  2. The second potential problem is in the implementation of the void doubleArrayCapacity function. You need to implement Course assignment operator in order that the statement temp[i] = array[i]; will do what you want.

Anyway, I recommend you to:

  1. Review the alignment of data members of the 'Course'
  2. Ensure that 'Course' has no complex data members and pointers.

Another option is to add serialize method to the Course class and deserializing constructor.

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

3 Comments

Thanks for your advice. This is my Course struct struct Course { char title[13]; int year; int units; char grade; };
And can you elaborate on your second point, implementing the Course assignment operator?
For such struct you really don't need Course& operator = (const Course& other);
0

You write size to the file, this tells you how many items there are. Then you open the file and read size. But you forgot to use size.

Change cap to size here:

fin.read(reinterpret_cast<char*>(&size), sizeof(size));
doubleArrayCapacity(courses, cap, size);

//fin.read(reinterpret_cast<char*>(courses), cap * sizeof(Course));    
fin.read(reinterpret_cast<char*>(courses), size * sizeof(Course));

2 Comments

When I do that I get this error Segmentation fault (core dumped)
You haven't shown the rest of your code. Update your question to make Minimal Complete Verifiable Example

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.