簡體   English   中英

加速序列化:指針跟蹤如何工作?

[英]Boost serialization: How does pointer tracking work?

指針跟蹤在Boost序列化中如何工作? 我使用它來序列化系統組件之間的消息,給人的印象是我得到了很多不正確共享的對象。 如果我使用共享指針指向要序列化的對象,並且一個新對象的地址與之前被刪除的先前對象的地址相同,是否會錯誤地將其捕獲為共享引用?

想象一下用於序列化的對象:

用於序列化的示例對象

A開始,使用堆棧來確定我們仍然需要訪問的內容:

  1. 參觀A
  2. BC
  3. 彈出並訪問C
  4. 按'D'
  5. 其他刪除B並將其替換為D
  6. 彈出並訪問“ D”
  7. 彈出並訪問被標記為B ,但現在也變成了D

然后,您將遇到一種情況,該情況將被錯誤地捕獲為共享參考。 如果在串行化開始和結束之間有任何 事情可以更改任何指針或它們指向的對象,那么您將獲得不一致的狀態。

簡短的回答:是的,這發生了。

原因是(因為可以從其他答案和評論中得出結論)這是對序列化庫的意圖的輕微濫用。 因此,如果在一天的過程中使用增強序列化來記錄對象(例如,並非所有對象在序列化開始時都在內存中),並且對象碰巧具有相同的地址,則它們將被錯誤地共享。 這在共享指針上發生,但在常規指針上也發生(據我所知)。

若要解決此問題,請避免使用指針或將其關閉。 如果您關閉跟蹤,並且仍然對共享指針進行序列化(盡管這可能不理想,但是我目前正在這樣做),boost中的一些硬編碼檢查會抱怨跟蹤被關閉。 為了解決這個問題,我入侵了我的boost頭文件的本地副本(並且必須在用於編譯的每個更新和系統上都這樣做)(盡管這很簡單,編譯器指向正確的行,並且清楚地記錄了它們) 。 如果您可以選擇不使用指針而工作,那么您就不必為此煩惱了。

除此之外,盡管日志記錄工作得很出色,所以不要將其從使用boost序列化功能關閉(如上面的某些注釋所示)。

要記錄到達的對象,只需使用void Log(Msg* msg) {ar & NVP(msg);}並按以下方式讀取它們:

Msg* Read() {
    Msg* msg(0); 
    try {ar & NVP(msg);}
    catch (boost::archive::archive_exception const&) { }
    return msg; 
}

您將在Read函數上方調用,直到返回的指針為NULL指針為止,然后您便知道日志已完成。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM