|
Boost : |
From: Robert Ramey (ramey_at_[hidden])
Date: 2002-05-23 10:35:58
I am embarassed to admit that this issue never occured to me. Rather I would be but no one else mentioned either. I would like to defer consideration of this for a an enhancement round if there is sufficient interest in the library as it stands.
I did read your long email and appreciate the thought that went into it. I don't know how carerfully you have looked at the library but it may interest you to check out the implementation. It turns out that input archives keep a record of each pointer loaded. This could probably enanced to keep track of objects created so they could be destroyed on detecting an exception.
Anyway, this is interesting. but I would prefer to get the library built on a couple more platforms and get it accepted with the current feature set. If this goes well, your enhancement would be included in version 2.
Robert Ramey
> -----Original Message-----
>From: boost-request_at_[hidden] [SMTP:boost-request_at_[hidden]]
>Sent: Wednesday, May 22, 2002 10:02 AM
>To: boost_at_[hidden]
>Subject: Boost Digest, Vol 13, Issue 1
>Date: Wed, 22 May 2002 20:28:22 +0500
>From: "Vahan Margaryan" <vahan_at_[hidden]>
>To: <boost_at_[hidden]>
>Subject: Re: [boost] Serialization Draft Submission # 3 - Final Draft
>Message-ID: <001101c201a5$4f3dff90$2709a8c0_at_[hidden]>
>References: <01C1FCD0.0A5982C0_at_[hidden]>
>Content-Type: text/plain;
> charset="iso-8859-1"
>MIME-Version: 1.0
>Content-Transfer-Encoding: 7bit
>Precedence: bulk
>Message: 15
Hello Robert,
Have you considered solving the exception-safety implications of the pointer
serialization mechanism? There is a problem when an exception occurs during
loading of objects that are pointed to from several locations.
The problem.
Consider this, I have a class A that holds a single pointer to another
object of class A:
class A{ ...
A* other_;
};
A doesn't own that pointer - it is passed to it via constructor and is not
deleted in the destructor.
Then I have a class AManager. AManager holds a vector of A*. In one of the
member functions, AManager creates 100 A objects, links them via their
other_ members and pushes them into the vector. In the destructor, AManager
destroys the elements of the vector (thus, it owns them).
What happens when I restore an object of the type AManager and something
wrong happens? It goes like this:
1. AManager tries to load a vector. It tries to read in the first element of
the vector.
2. Loading the first element means loading the other_ member of the first
element.
3. Since all the A objects are linked together, the process loads all the
other A objects too, while still in the context of loading the first object.
All the A objects are allocated.
4. Then the loading function of the first object fails with an exception
(corrupted file, end-of-file, or something else).
5. AManager attempts to destroy the loaded objects by destroying the
elements of the vector. But the vector contains no elements.
6. All the objects allocated while loading AManager are left in memory,
memory leaks result.
A possible solution.
Generally speaking, there's no quick fix for this, AFAIK. The way I solved
it was by indicating whether the pointer was owned by the object.
When an object owns its member pointer, it says so to the loading function:
load(ar, ptr, owns( )); //owns is a type
When the object doesn't own its member pointer, it just says:
load(ar, ptr);
(I use overloading, because the ownership status is usually known at compile
time.)
Now the lookup table that stores pointers that have been new-ed (to check
for multiple references to the same object) also holds a boolean value for
each pointer, that indicates whether the ownership of the given pointer has
been taken.
When an exception occurs, the system iterates over the items in the
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk