是否保证类在程序运行之间在内存中具有相同的组织?

时间:2012-01-28 23:40:23

标签: c++ class memory-management load

我正在尝试在我的小游戏中实现保存/加载功能。为了实现这一点,我有一个中心类,它存储游戏的所有重要变量,如位置等。然后我将这个类作为二进制数据保存到文件中。然后只需将其加载回加载功能。这似乎在大部分时间都有效,但是如果我改变某些东西然后尝试进行保存/加载,程序将因内存访问冲突而崩溃。那么,类的保证在程序的每次运行时都在内存中具有相同的结构,或者数据可以像结构一样随机排列吗?

对耶稣的回应 - 我的意思是班级内的数据,所以如果我将班级保存到磁盘,当我把它加载回来时,一切都会很好地适应。

保存

fout.write((char*) &game,sizeof Game);

加载

fin.read((char*) &game, sizeof Game);

4 个答案:

答案 0 :(得分:4)

你的方法非常脆弱。有许多限制,它可以工作。在典型情况下,这些限制不值得让您的用户(或您自己!)受到影响。

一些限制:

  • 从不参考外部存储器(例如指针或参考)
  • 禁止ABI更改/差异。常见情况:32对64的内存布局和自然对齐会有所不同。用户将需要为每个ABI创建一个新的“游戏”。
  • 不兼容端。
  • 改变你的类型布局会打破你的游戏。更改编译器选项可以做到这一点。
  • 您基本上只限于POD数据。
  • 使用偏移而不是指针来引用内部数据(此引用将位于连续的内存中)。

因此,您可以在非常有限的情况下安全地使用此方法 - 这通常仅适用于系统的组件,而不是整个游戏状态。

由于这是标记的C ++,“boost - Serialization”将是一个很好的起点。它经过了充分的测试,并为您提供了许多复杂性。

答案 1 :(得分:2)

即使这样可行,也就是不要这样做。在字节级定义文件格式并写入合理的“转换为文件格式”和“从文件格式转换”功能。您实际上知道文件的格式。你将能够扩展它。较新版本的程序将能够从旧版本中读取文件。并且您将能够更新您的平台,构建工具和类,而不必担心会导致程序崩溃。

答案 2 :(得分:1)

是的,每次程序运行时,类和结构在内存中都会有相同的布局。虽然我不能说标准是否强制执行此操作。由C ++编译器生成的机器代码使用“硬编码”偏移来访问类型字段,因此它们是固定的。实际上,只有修改C ++类定义(字段大小,顺序,虚拟方法等),使用不同的编译器编译或更改编译器选项时,布局才会发生变化。

只要类型是POD且没有指针字段,只需将其转储到文件并使用完全相同的程序将其读回即可。但是,由于上述问题,这种方法在版本控制和互操作性方面非常不灵活。

[编辑]

要回复您自己的编辑,请不要使用“游戏”对象执行此操作!它肯定有指向其他对象的指针,这些对象将不再存在于内存中,或者在您重新加载文件时将存在于其他位置。

答案 3 :(得分:0)

您可能需要查看this

不保证类在内存中具有相同的结构,因为每次创建类时,指针都可以指向内存中的不同位置。

但是,如果没有发布代码,很难肯定地说问题在哪里。