将动态分配的结构写入文件
假设我们有以下结构:
struct Something { int i; };
如果我想在文件中写入这种类型的任何数据(动态分配),我这样做:
struct Something *object = malloc(sizeof(struct Something)); object->i = 0; // set member some value FILE *file = fopen("output_file", "wb"); fwrite(object, sizeof(struct Something), 1 file); fclose(file);
现在,我的问题:
我们如何使用包含指针的结构来做到这一点? 我使用相同的方法测试,它工作正常,数据可以读取,但我想知道是否有任何风险?
你想要的是序列化 。 另请参见XDR (便携式二进制数据格式)和libs11n (C ++二进制序列化库); 您经常关心数据的可移植性:能够读取某些不同计算机上的数据。
“序列化”意味着将一些复杂的数据结构(例如列表 , 树 ,向量甚至你的Something
……)“转换”成(串行)字节流(例如文件,网络连接等……) ),倒退。 处理循环数据结构或共享子组件可能是棘手的。
你不想在文件中写入原始指针(但你可以),因为写入地址可能在下一次执行你的程序时没有任何意义(例如因为ASLR ),即当你读到数据再次。
阅读有关应用程序检查点和持久性的信息 。
出于实际原因(特别是易于调试和弹性以及小软件演化),通常最好使用一些文本数据格式(例如JSON或Yaml )来存储此类持久数据。
您可能也对数据库感兴趣。 首先看一下sqlite ,然后再看看DBMS(“关系” – 或者基于SQL的 – 比如PostGreSQL , NoSQL就像MongoDB )
问题不在于编写单个动态分配的struct
(因为您主要要编写数据内容,而不是指针,因此对于编写malloc
-ed struct
或本地分配struct
是相同的),它是序列化复杂数据使用大量奇怪的内部指针的结构!
请注意,复制垃圾收集器使用类似于序列化算法的算法(因为两者都需要扫描复杂的引用图 )。
此外,在今天的计算机上,磁盘 – 或网络 – IO比CPU慢很多(例如一百万次),因此在写入文件之前进行一些重要的计算是有意义的。