Re: [Boost-users] [smart_ptr] Sole ownership of shared_ptr?

On Apr 6, 2008, at 5:48 PM, Joseph Thomson wrote:
Hi everyone,
Over the past few days I have been trying to integrate Boost smart pointers into my system, which is basically a manager (ObjectManager) class which creates, destroys, and keeps track of instances of another class (Object).
The manager keeps a std::map of instances of type shared_ptr. The manager has a createObject() method which returns a shared_ptr instance to the user, thus the user becomes an owner of the object, alongside the manager. My problem arises because I want objects to _always_ be destroyed when the manager method destroyObject() is called. I realise that part of the reason to use smart pointers is to prevent data from being deleted while a reference to it still exists, but I figure they are still worth using just for the safety aspect.
I am also in the position of attempting to integrate shared_ptr into my application framework, so I am definitely a neophyte in this area. (So please take my comments with a grain of salt.) However, I have a couple of thoughts. (1) Your idea of storing both a weak_ptr and a true pointer to the object strikes me as dangerous. Any time you use the true pointer instead of locking the weak_ptr, you run the risk that the true pointer is not valid. This would, of course, invalidate one of the major points in using the shared_ptr/weak_ptr mechanism in the first place. I don't think that the overhead of converting the weak_ptr via lock() is sufficiently high to forego the advantages of the mechanism. But of course, only performance testing can verify that. [My own bias is to build a safe mechanism first, then only weaken it if performance measurements verify that this step is necessary.] (2) If you have, in fact, built a mechanism where you *know* that it is safe to use the true pointer instead of converting the weak_ptr, then I wonder if starting with a shared_ptr strategy is the best way to go in the first place. Since you only want one lock on the file (rather than shared ownership), wouldn't it be better to use auto_ptr? That pattern seems better suited to your overall approach -- if (and only if) you can be sure that a user will never use a deleted true pointer. Cheers, Rick Aurbach, Ph.D. President and Chief Engineer Aurbach & Associates, Inc. 8233 Tulane Avenue, Suite B St. Louis, MO 63132 www: http://www.aurbach.com/ eMail: support@aurbach.com [business] rick@aurbach.com [personal] Fax: 314/678-0869 Phone: 800/774-7239 314/726-1321 "If it ain't broke and you haven't fixed it recently, it probably needs to be rewritten." - Richard Aurbach (1948- ) "Beware of bugs in the above code; I have only proved it correct, not tried it." - Donald Knuth, computer scientist (1938- ) "If in the last few years you haven't discarded a major opinion or acquired a new one, check your pulse. You may be dead." - Gelett Burgess (1866-1951) "A life spent making mistakes is not only more honorable, but more useful than a life spent doing nothing." - George Bernard Shaw (1856-1950) "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong." - Richard Feynman (1918-1988) "The most likely way for the world to be destroyed, most experts agree, is by accident. That's where we come in; we're computer professionals. We cause accidents." - Nathaniel Borenstein (1957-)

Richard L. Aurbach wrote:
(1) Your idea of storing both a weak_ptr and a true pointer to the object strikes me as dangerous. Any time you use the true pointer instead of locking the weak_ptr, you run the risk that the true pointer is not valid. This would, of course, invalidate one of the major points in using the shared_ptr/weak_ptr mechanism in the first place. I don't think that the overhead of converting the weak_ptr via lock() is sufficiently high to forego the advantages of the mechanism. But of course, only performance testing can verify that. [My own bias is to build a safe mechanism first, then only weaken it if performance measurements verify that this step is necessary.]
(2) If you have, in fact, built a mechanism where you *know* that it is safe to use the true pointer instead of converting the weak_ptr, then I wonder if starting with a shared_ptr strategy is the best way to go in the first place. Since you only want one lock on the file (rather than shared ownership), wouldn't it be better to use auto_ptr? That pattern seems better suited to your overall approach -- if (and only if) you can be sure that a user will never use a deleted true pointer.
Thanks for your reply. Well, now that I think about it my method is not thread safe. The pointer could be deleted at any point during its use. I may re-consider since I haven't ruled out the use of multi-threading in the future. However, with a single thread, doesn't checking that the weak_ptr hasn't expired before any use of the raw pointer assure that the pointer is valid (assuming that the Object doesn't unexpectedly trigger its deletion in one of its methods)? This method still requires use of a weak_ptr for validation, and therefore auto_ptr wouldn't be sufficient, unless I am missing something? After a quick test of lock() vs. expired() vs. no check at all in my example, with 1,000,000,000 iterations of each I get 49 seconds with no check, 59 seconds with an expired() check, and 296 seconds when locking. So although locking is 25 times slower, it seems sufficiently fast enough to use in my application. Cheers, Joe -- View this message in context: http://www.nabble.com/-smart_ptr--Sole-ownership-of-shared_ptr--tp16528658p1... Sent from the Boost - Users mailing list archive at Nabble.com.

Actually, I think I have a better way which uses auto_ptr (or the boost ptr containers) as you suggested. It still isn't thread safe, but this isn't of immediate concern, and there are other methods for this anyway. Before, I was storing a map of shared_ptrs in the ObjectManager and a weak_ptr reference in any ObjectHandles to check if the object is still valid. Instead: - A map of auto_ptrs (or a ptr_map of Objects) would be stored in the ObjectManager. - On its creation, Object would create and store a shared_ptr<ObjectHandle>, passing a raw pointer to it in the process (don't worry, this is still safe). - Any user wanting to get access to the Object would request an ObjectHandle from ObjectManager, which would in turn request a copy of Object's shared_ptr<ObjectHandle>. - On its destruction (by ObjectManager), Object would inform its ObjectHandle of its destruction, and ObjectHandle would set an internal flag to indicate that it is expired. - ObjectHandle would handle any requests from the user by first checking the expiry flag, and then forwarding the call to Object using its stored raw pointer. The expiry flag is set by the Object itself, so there is no chance of the pointer being invalid when called. Any advice/thoughts are appreciated. Cheers, Joe -- View this message in context: http://www.nabble.com/-smart_ptr--Sole-ownership-of-shared_ptr--tp16528658p1... Sent from the Boost - Users mailing list archive at Nabble.com.
participants (2)
-
Joseph Thomson
-
Richard L. Aurbach