Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: would universal use of shared_ptr<> be equivalent to a gc?

This is just an academic question (I would never do this in real code):

If I were to use shared_ptr<> universally in my code, would the behavior be equivalent to a gc-collected language like Java?

If not, how would the behavior be different from a gc-embedded language? Which C++ construct would yield equivalent behavior compared to a gc-embedded language?

Note: In real coding, I strongly prefer the use of RAII and strict ownership over the use of any smart pointers. I also know that other less-generic pointers, unique_ptr<> would be more efficient. This question is just a query into smart-pointer equivalence.

like image 534
kfmfe04 Avatar asked Oct 22 '11 08:10

kfmfe04


People also ask

What is the purpose of the shared_ptr <> template?

std::shared_ptr is a smart pointer that retains shared ownership of an object through a pointer. Several shared_ptr objects may own the same object.

Why would you choose shared_ptr instead of unique_ptr?

Use unique_ptr when if you want to have single ownership(Exclusive) of resource. Only one unique_ptr can point to one resource. Since there can be one unique_ptr for single resource its not possible to copy one unique_ptr to another. Use shared_ptr if you want to share ownership of resource .

What happens when you move shared_ptr?

The reference count increases as a new shared_ptr is constructed, and it decreases as an owning shared_ptr is destroyed. One exception to that is the reference count is left unchanged when a shared_ptr is moved because the move-constructor transfers the ownership from the source to the newly constructed shared_ptr.

Should you use shared_ptr?

Use shared_ptr to manage the lifetime of objects: Whose ownership is shared (multiple "things" want the object lifetime extended) Where the order of release of ownership is non-deterministic (you don't know in advance which of the owners will be "last" to release the object).


2 Answers

No, there'd be a couple of important differences:

  • You would get a memory leak any time you have a cyclic reference. A garbage collector can handle cycles, ref-counting can't.
  • You would avoid any stalls or pauses because no garbage collection ever occurs. On the other hand, you'd likely spend more total CPU time cleaning up resources, because the amortized cost of an occasional garbage collection is pretty low, and ref-counting can be relatively expensive if you do it on everything.

Obviously the first point is the killer. If you did this, many of your resources wouldn't get freed, and you'd leak memory and your app just wouldn't behave very well.

Which C++ construct would yield equivalent behavior compared to a gc-embedded language?

None. C++ doesn't have a garbage collector because there's no way to implement a correct, reliable one. (Yes, I'm aware of Boehm's GC, and it's a good approximation, but it's conservative, and doesn't detect all references, only the ones it can be 100% sure of. There is no way, in a general C++ program, to implement a garbage collector that Just Works(tm))

like image 164
jalf Avatar answered Oct 26 '22 22:10

jalf


@jalf says this in his answer:

You would avoid any stalls or pauses because no garbage collection ever occurs.

While smart pointers (or any reference counting scheme) have no pause while garbage collection occurs, you can get a pause if you null the last external pointer to a large data structure, and trigger a cascade of reference count adjustments and finalizations for each node in the data structure. While a smart smart-pointer implementation could ameliorate this, you'd be sacrificing immediate reclamation ... which some people claim is an advantage of smart pointers.

Also, there is an overhead of a few instructions each time you assign to a smart pointer-typed variable, and the overheads of allocating an object is greater.

like image 37
Stephen C Avatar answered Oct 27 '22 00:10

Stephen C