2015-02-06 109 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慢很多(例如一百萬次),所以在寫入文件之前做一些重要的計算是有意義的。