2012-02-11 66 views
4

我知道這很奇怪,但我只是玩得開心。在進程之間移動STL對象

我試圖發送一個std::map經由插座兩個機器之間的兩個過程之間(使用放置在存儲器的固定區域新實例化):MasterSlave。我使用的地圖有此typedef

// A vector of Page objects 
    typedef 
     std::vector<Page*, 
      PageTableAllocator<Page*> > 
     PageVectorType; 

    // A mapping of binary 'ip address' to a PageVector 
    typedef 
     std::map<uint32_t, 
      PageVectorType*, 
      std::less<uint32_t>, 
      PageTableAllocator<std::pair<uint32_t, PageVectorType*> > > 
     PageTableType; 

PageTableAllocator<T>類是負責分配內存的任何STL容器可能想/需要到內存中的固定位置。例如,所有Page對象和STL內部結構正在這個固定存儲器區域中被實例化。這確保std::map對象和分配器都是兩個放置在一個固定的內存區域。我已經使用GDB來確保映射和分配器的行爲正確(所有使用的內存在固定區域,應用程序的正常堆棧上都沒有任何內存)。

假設Master啓動時,初始化它的所有STL結構和特殊的內存區域,將出現以下情況。 Slave開始,打印出其版本的頁表,然後查找MasterSlave找到一個主文件,刪除其版本的頁表,複製Master的版本的頁表(和特殊內存區域),併成功將其打印出Master的頁表版本。從我在GDB中完成的操作中,我可以執行許多隻讀操作。

嘗試添加到新複製的PageTableType對象時,Slave錯誤在分配器的void construct (pointer p, const T& value)方法中。作爲p傳入的值指向已分配的內存區域(根據Master的版本std::map)。

我不知道C++對象結構什麼,但我猜從Slave的版本的PageTableType必須即使我被掛在該對象的狀態全部更換內存的PageTableType及其分配使用。 我的問題是,如果這是一個有效的關注。 C++是否在對象實例化的內存區域之外維護某種對象狀態?

所有在地圖中使用的對象都是非POD。分配器也是如此。

+0

您在哪裏存儲確定共享內存哪部分已被分配的元數據? – 2012-02-11 20:37:24

+0

我在應用程序中重新定義了所有對內存分配代碼('malloc','free'等)的調用。當一個節點分配內存時,偏移記錄在這個'std :: map'對象中。當「從屬」嘗試更新地圖時(傳輸後),它會發生故障。 – sholsapp 2012-02-11 20:41:21

+0

這就是我的意思。記錄*其中*? – 2012-02-11 20:41:42

回答

3

爲了回答您的具體問題:

不C++保持某種對象狀態的那個對象是在實例化的內存區域之外?

答案是沒有。沒有其他數據結構設置爲「跟蹤」對象或任何類別。 C++使用顯式的內存分配模型,所以如果您選擇負責分配和解除分配,那麼您可以完全控制。

我懷疑有一些錯誤代碼的某個地方,既然你認爲的代碼是正確的你發明了一些其他的原因,你的代碼可能會失敗,並按照這條道路來代替。我會退後一步,仔細檢查你的代碼現在正在工作的方式,看看你能否確定問題。雖然STL類很複雜(特別是std::map),但它們最終只是代碼,並且在那裏沒有隱藏的魔法。