【问题标题】:C++ Serializing a dynamic arrayC++ 序列化动态数组
【发布时间】:2016-10-27 06:14:58
【问题描述】:

我认为我的二进制文件写入不正确。我们应该创建一个程序,让我们可以将大学课程添加到包含成绩、单位等详细信息的列表中。每当我们向数组中添加项目时,我们还应该将数组容量加倍(因此函数 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;
  }

如果我将 4 个项目添加到我的数组中,则程序可以正常工作。一旦我到达 5 个对象,就会发生错误。文件未正确回读,第 5 项被读取为 null 或零。我想我没有正确地将我的数据输出到我的二进制文件中。谁能看到我做错了什么?

【问题讨论】:

  • 当新条目不适合现有容量时,通常您只会将容量翻倍,而不是每次添加条目时。每次将大小加倍将有效地将未初始化的数据插入到您的数组中。
  • 顺便说一句:将这些数据按原样写入磁盘根本不能跨不同平台移植,因为数字可能有不同的表示形式(大端与小端),并且数据类型的对齐可能有不同的要求,导致结构中的不同填充。

标签: c++ arrays serialization


【解决方案1】:

如我所见,这里有 2 个潜在问题

  1. 第一个问题在序列化中,fout.write(reinterpret_cast&lt;char*&gt;(courses), cap * sizeof(Course)); 序列化的正确性取决于Course 对象的数据成员的内部布局和对齐方式。
  2. 第二个潜在问题是void doubleArrayCapacity 函数的实现。您需要实现 Course 赋值运算符,以便语句 temp[i] = array[i]; 执行您想要的操作。

无论如何,我建议你:

  1. 查看“课程”数据成员的对齐方式
  2. 确保“课程”没有复杂的数据成员和指针。

另一种选择是将serialize 方法添加到Course 类并反序列化构造函数。

【讨论】:

  • 感谢您的建议。这是我的课程结构struct Course { char title[13]; int year; int units; char grade; };
  • 您能否详细说明您的第二点,实现Course 赋值运算符?
  • 对于这样的结构你真的不需要Course&amp; operator = (const Course&amp; other);
【解决方案2】:

您将size 写入文件,这会告诉您有多少项目。然后你打开文件并阅读size。但是您忘记使用size

在此处将 cap 更改为 size

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));

【讨论】:

猜你喜欢
  • 2012-12-12
  • 2023-03-19
  • 2014-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-12
  • 1970-01-01
相关资源
最近更新 更多