所以我有一个看起来像这样(或多或少)的结构:
typedef struct AST_STRUCT
{
enum {
AST_OBJECT,
AST_REFERENCE,
AST_VARIABLE,
AST_VARIABLE_DEFINITION,
AST_VARIABLE_ASSIGNMENT,
AST_VARIABLE_MODIFIER,
AST_FUNCTION_DEFINITION,
AST_FUNCTION_CALL,
AST_NULL,
AST_STRING,
AST_CHAR,
AST_FLOAT,
AST_LIST,
AST_BOOLEAN,
AST_INTEGER,
AST_COMPOUND,
AST_TYPE,
AST_BINOP,
AST_NOOP,
AST_BREAK,
AST_RETURN,
AST_IF,
AST_ELSE,
AST_WHILE,
AST_ATTRIBUTE_ACCESS,
AST_LIST_ACCESS,
AST_NEW
} type;
struct AST_STRUCT* variable_value;
}
现在,我想将此结构写入磁盘,将其序列化为.dat
文件。
问题是,如您所见,它有一个名为variable_value
的字段。
我正在使用此功能将其写入磁盘: https://www.geeksforgeeks.org/readwrite-structure-file-c/
我还使用该文章中的其他功能从磁盘读取它。
似乎该结构上的variable_value
字段未正确加载。
如何将整个结构写入磁盘并维护variable_value
字段的数据?
我首先想到的是将variable_value
字段转储到一个单独的文件中,然后在加载后将其“链接回”到结构中,但是也许还有另一种方法?
答案 0 :(得分:0)
您正在尝试序列化链接的结构(我假设是一棵树,名称为“ AST”)。
如果我们有一秒钟想像您成功完成了该操作并将其写入磁盘,那么在将其加载回磁盘时,您将为树中的链接分配内存,但是这些内存块的地址(指针的值)不能保证与旧的相同。您将无法重建树。
因此,您不能将地址的值用作磁盘上的链接。您将需要使用其他方法。如今,流行的方法是JSON格式,假设您在树中没有交叉链接或反向链接,该格式将对您有用。
所以您需要一个JSON C库。我从没用过,但是在2秒内找到了一对:
答案 1 :(得分:0)
JSON和xml是非常好的格式。他们确实有恢复对同一对象的多个引用的问题,但是即使它们也可以解决。
如果数据是简单的链接列表,则可以简单地按顺序还原对象,并在还原对象时自行修复链接列表。如果数据结构比这复杂,那么您需要一个更通用的解决方案。
如果您确实想将数据另存为二进制文件,则在重新加载时需要修复指针。这样做的主要方法是保留已保存地址与新分配地址的映射。如果您真的不喜欢发出保存的地址的想法,则可以使用序列号来表示找到的每个唯一地址。
对于保存的每个对象,在保存对象本身之前,必须记录其标量地址和对象的类型。
对于保存的每个指针,您需要保存标量地址,并“记住”以以后保存该引用对象。
还原时,还原对象时,需要根据对象的类型加载该对象,并创建一个映射条目,以显示已保存的地址如何变成已还原的地址。
如果对象包含任何指针,则通过应用该映射可以找到存储在这些指针中的地址。但是,您通常会发现尚未为该指针加载对象,因此您还需要记录从保存的标量地址到指针地址的映射。然后,您可以在加载完成后修复所有这些未完成的指针,也可以在加载该对象后对特定的引用对象进行操作。
您需要格外小心以处理支持多重继承的对象,注意指针不会指向对象的根。
但是,否则,这几乎是您所需要的,再加上版本控制,字节序和填充的考虑-如果您关心要保存的数据的寿命。