【问题标题】:Memory allocation of a structure in CC中结构的内存分配
【发布时间】:2014-06-24 10:51:36
【问题描述】:

我在Linux平台上用libX11libpthread用C语言设计一个小游戏,所有关卡信息都填充到struct数组Level[Level_Amount]中。

struct Pos
{ 
   int X; 
   int Y; 
};

struct Pos_Info
{ 
   int Flag; 
   int Drctn; 
   int Layer; 
   struct Pos Postn; 
   int Color; 
};

struct In_Out_Chnl
{ 
   struct Pos Drctn[Channel_Amount]; 
};

struct Check_Point
{ 
   int Remain; 
   struct Pos Postn[Chk_Pnt_Amount]; 
};

struct Level_Info
{ 
   char Map[Rbn_Col][Rbn_Row]; 
   struct Pos_Info Draw, Rcvd;
   struct Check_Point Chk_Pnt; 
   struct In_Out_Chnl Channel; 
};

struct Level_Info Level[Level_Amount];

我很困惑这是否是从文件中读取和写入结构数组的好方法,如下所示:

FILE *fp;
fwrite(&Level, sizeof(struct Level_Info), Level_Amount, fp);
fread (&Level, sizeof(struct Level_Info), Level_Amount, fp);

结构体(具有不同类型的元素)的内存分配会与编译器或 CPU 不同吗?

有没有更好的方法来安全地保存和读取整个结构?

【问题讨论】:

  • 在网上搜索数据序列化
  • 是的,可能会有所不同。您应该有自己的方法来一次读取/写入一个字段的结构。这是使用 OO 语言可能会有所帮助的典型情况之一。
  • 序列化不是小问题,尝试一些已经实现的解决方案,例如troydhanson.github.io/tpl/index.html
  • @petrbel 谢谢。我访问了该网站,目前 tpl 不支持内部结构上的定长数组后缀。我认为我应该自己从头开始做所有事情。 :-)
  • 您的问题与内存分配有关(例如malloc),您没有告诉我们什么例如Channel_Amount 是。我相信libsdlJSON -with Jansson library- 和 flexible array members 可能对你有用。

标签: c memory-management struct


【解决方案1】:

您可以按照您的建议进行操作,但请记住,您需要坚持您拥有的结构布局。这意味着

  • 您无法更改数组维度
  • 您不能添加或删除数据成员
  • 您不能在结构中包含指针或类似数据的指针(您似乎没有)
  • 文件中的 int 必须与内存中的 int 大小相同(不能轻易跨平台工作)
  • 文件中的 int 必须与内存中的 int 具有相同的字节顺序(不能轻易跨平台工作)

关于 int 问题,您可以包含stdint.h 并使用int32_t 之类的类型。对于字节顺序,您可以将文件中的数据保持为网络字节顺序,然后使用套接字转换函数ntohsntohl 进行字节顺序转换。

请始终牢记:如果您从文件中读取数据,您正在处理的是外部输入,因此请准备好输入完全是垃圾(攻击者可能已经更改了它)。

您可能还想在 Google 上搜索术语 serialization,它表示将数据从内存写入持久存储并再次取回的过程。

【讨论】:

    【解决方案2】:

    您可以这样做,但请注意以下几点:

    此外,我建议您使用内存映射——它不仅会提供更高的性能,而且通过一些操作系统特定的代码,您可以教它在结构变大时自动增长文件;

    http://en.wikipedia.org/wiki/Memory-mapped_file

    【讨论】:

      猜你喜欢
      • 2014-12-18
      • 1970-01-01
      • 2013-06-05
      • 1970-01-01
      • 2021-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多