2011-03-16 117 views
1

我遇到了VS2010 VC++中的指針數據序列化和反序列化問題。基本上,該程序無法序列化和反序列化CObList *指針數據。源代碼執行處理該過程的正常步驟:使用MFC CArchive序列化指針(使用mfc100d.dll,CMemFile)

1)MyObject從CObject繼承;

2)我們在類聲明(第1行)中添加了DECLARE_SERIAL(MyObject);

3)我們添加IMPLEMENT_SERIAL(爲MyObject,MyParentObject,SCHEMA_VERSION)

//Where MyParentObject is inherited from CObject (indirectly, there're a few more levels of objects), SCHEMA_VERSION is just a version control CONSTANT we use 

4)然後,我們已經超負荷

void MyObject::Serialize(CArchive& ar) 
{ 
    BOOL b; 
    ..... 
    ... (some other simple variables with default values) 

    MyParentObject::Serialize(ar); 

    if (ar.IsStoring()) 
    { 
     ar << m_sTitle; 
     ar << m_pObjectsList; 
    } 
    else 
    { 
     ar >> m_sTitle; 
     ar >> m_pObjectsList; 
    } 
} 

注:MyParentObject ::序列化是相應的執行。 CObList * m_pObjectsList;在頭文件中正確聲明。

當試圖從「ar >> m_pObjectsList」反序列化時,程序引發了訪問衝突(MyApp.exe中的0x52e77b2c(mfc100d.dll)的第一次機會異常:0xC0000005:訪問衝突讀取位置0x00000004)。

然後我開始測試並將複雜指針m_pObjectsList更改爲一個簡單的指向CString的指針。將指針反序列化爲CString時,同時發生同樣的錯誤。如果我簡單地通過CString序列化和反序列化(沒有指針),它可以正常工作。似乎有些指針串行化被破壞了。

也許MFC100d在64位OS調試器中不適用於W32程序?這在調試模式和發佈模式下都會導致問題。發生了什麼?我已經耗盡了我的資源,任何方向或靈感都非常感謝。謝謝大家。

+0

你初始化了'm_pObjectsList'嗎? – Erik 2011-03-16 19:56:25

+0

這是遺留的遺留代碼庫。我看到m_pObjectsList = new CObList;在NewObjectsList方法中,並且m_pObjectsList = NULL;在構造函數代碼中。 – 2011-03-16 20:01:14

+0

我認爲這表示它已初始化。 – 2011-03-16 20:08:30

回答

3

指針不能是序列化

沒有保證

  1. 應用程序讀取文件 將有機會獲得的 存儲在同一地區
  2. 操作系統將將數據放在同一 地方
  3. 應用讀取文件 將被放置在同一個地方 內存

一個想法是通過使用文件偏移來模擬指針。因此,一個對象位於文件相對於開始的位置。這是困難的。

更好的辦法是寫出全部的數據,並讓應用程序讀取數據將數據放入內存中。這也使應用程序可以自由地使用任何數據結構來存儲數據。

+0

同意 - 您需要序列化列表中的每個對象,而不是指向列表的指針。 – Jeff 2011-03-17 05:39:52

+0

在MFC 6(Visual Studio 6)之前和之前,編譯器能夠很好地處理這個指針序列化。我認爲所有的MFC都是在收緊內存分配安全/策略之後才實現的。 – 2011-03-23 16:32:09

+0

@Jerry:您可以將指針從您的機器存儲到文件中。我把文件讀到我的機器上。請問指針中的指針或值是否仍然在我的機器上有效?如果我正在運行Windows NT並在Mac上運行,該怎麼辦?無法保證任何操作系統每次啓動時都會將程序加載到完全相同的位置;因此指針的內容可能無效。冒險。 – 2011-03-23 16:49:00