Повысить сериализацию: как работает отслеживание указателя? - PullRequest
1 голос
/ 22 августа 2011

Как работает отслеживание указателей в ускоренной сериализации? Я использую его для сериализации сообщений между компонентами системы, и у меня сложилось впечатление, что я получаю много неправильно используемых объектов. Возможно ли, что если я использую общие указатели на объекты, которые я хочу сериализовать, и у нового объекта будет тот же адрес, что и у предыдущего объекта, который был удален после этого, он будет неверно зафиксирован как общая ссылка?

Ответы [ 2 ]

0 голосов
/ 23 ноября 2011

Краткий ответ: да, это происходит.

Причина (как можно заключить из других ответов и комментариев) в том, что это незначительное злоупотребление тем, что должна делать библиотека сериализации.Таким образом, если кто-то использует расширенную сериализацию для записи объектов в течение дня (например, не все объекты находятся в памяти в начале сериализации), и объекты имеют одинаковый адрес, они будут неправильно распределены.Это происходит на общих указателях, но также и на обычных указателях (насколько я понимаю).

Чтобы устранить эту проблему, либо избегайте указателей, либо отключите отслеживание.Если вы отключите отслеживание и по-прежнему сериализуете общие указатели (что я и делаю в настоящее время, хотя это может и не быть идеальным), несколько жестко закодированных проверок в надстройке жалуются на отключение отслеживания.Чтобы обойти это, я взломал мою локальную копию заголовков наддува (и должен был делать это при каждом обновлении и системе, используемой для компиляции) (хотя это довольно просто, компилятор указывает на правильные строки, и они четко задокументированы),Если у вас есть возможность работать без указателей, вы избавите себя от этой проблемы.

Помимо этого, ведение журнала работает блестяще, поэтому не стоит отключать использование для этого расширенной сериализации (некоторые комментариипредложенное выше).

Чтобы регистрировать объекты по мере их поступления, просто используйте 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 выше, пока не вернется указательэто нулевой указатель, тогда вы знаете, что журнал завершен.

0 голосов
/ 22 августа 2011

Представьте для объектов для сериализации следующее:

Example objects for serializing

Начиная с A, используя стек для определения того, что нам еще нужно посетить:

  1. Визит A
  2. Push B, C
  3. Pop and Visit C
  4. Push 'D'
  5. Что-тоelse удаляет B и заменяет его на D
  6. Pop и зайдите в 'D'
  7. Pop и посетите то, что было помечено как B, но теперь оно действительно D

Тогда у вас возникнет ситуация, которая будет неверно воспринята как общая ссылка.Если что-либо может изменить любого указателей или объектов, на которые они указывают, между началом сериализации и его концом, то вы получите несовместимое состояние.

...