2015-02-06 83 views
0

假设我们有以下结构:写动态分配结构到文件

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

现在,我的问题:

我们如何做到这一点与结构什么包含指针?我使用相同的方法测试,它工作正常,数据可以被读取,但我想知道是否有任何风险?

+4

指针只在程序的特定实例中才有用。如果你将一个指针写入一个文件,那么稍后将它读回到其他进程中,这将只是一个随机数并且会导致严重问题 - 新实例的内存布局/使用情况将完全不同。 – 2015-02-06 19:00:00

+2

如果您正在讨论像链接列表这样的结构,那么按照无指针的顺序编写数据。阅读时,您需要在读取数据后重新创建带有指针分配的列表。 – 2015-02-06 19:00:41

回答

2

你想要什么叫serialization。另请参阅XDR(便携式二进制数据格式)& libs11n(C++二进制序列化库);您经常关心数据可移植性:能够读取某些不同计算机上的数据。 (串行)字节流(例如文件,网络连接等)“串行化”意味着将某些复杂数据结构(例如listtree,矢量或甚至Something ...)“转换”等等......),并向后。处理循环数据结构或共享子组件可能会很棘手。

你不想在文件内写入原始指针(但你可以),因为写入的地址在你的程序的下一次执行中可能没有任何意义(例如因为ASLR),即当你我会再次读取数据。另外请参阅application checkpointingpersistence

对于实际的理由(尤其是缓解调试和弹性w.r.t.小软件进化)通常最好使用一些textual数据格式(例如像JSONYaml)来存储这样的持久性数据。您可能也有兴趣databases。先看看sqlite,也为DBMS(“关系” - 或者SQL based-的像PostGreSQLNoSQL的像如MongoDB

问题不在于写一个动态分配struct(因为你想大多写的数据内容,而不是指针,所以它与fwrite一样malloc -ed struct或本地分配一个),它是序列化复杂的数据结构,它使用了很多奇怪的内部指针!

请注意,复制garbage collectors使用类似于序列化算法的算法(因为两者都需要扫描参考的复杂graph)。另外,在今天的计算机上,磁盘或网络IO比CPU慢很多(例如一百万次),所以在写入文件之前做一些重要的计算是有意义的。