指针跟踪如何在boost序列化中起作用?我用它来序列化系统组件之间的消息,我的印象是我得到了很多不正确的共享对象。是否有可能如果我使用共享指针到我想要序列化的对象,并且新对象恰好具有与之前被删除的对象相同的地址,那么这将被错误地捕获为共享引用?
答案 0 :(得分:0)
想象一下序列化对象的以下内容:
从A
开始,使用堆栈确定我们仍需要访问的内容:
A
B
,C
C
B
的内容,但现在真的是D
然后您的情况将被错误地捕获为共享引用。如果任何可以更改指针的任何,或者它们指向序列化开始和结束之间的对象,那么你将得到一个不一致的状态。
答案 1 :(得分:0)
简短回答:是的,这种情况发生了。
原因是(可以从其他答案和评论中得出结论),这是对序列化库的意图的轻微滥用。因此,如果使用boost序列化来记录一天中的对象(例如,在序列化开始时并非所有对象都在内存中),并且对象碰巧具有相同的地址,则它们将被错误地共享。这发生在共享指针上,也发生在常规指针上(据我所知)。
要解决此问题,请先避开指针,或关闭跟踪功能。如果你关闭跟踪,仍然序列化共享指针(我现在这样做,虽然这可能不太理想),在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指针,然后你知道日志已经完成。