Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shared void pointers. Why does this work?

Tags:

To solve a very peculiar problem in my application I need a shared-pointer to allocated data, but to the outside world, the underlying data type should remain hidden.

I could solve this by making some kind of Root class of which all my other classes inherit, and use a shared_ptr on this Root class, like this:

std::shared_ptr<Root> 

However:

  • I don't want all my classes to inherit from this Root class just to be able to have this shared pointer
  • Sometimes I want to return a shared pointer to std::vector, or std::list, or std::set, ... which obviously don't inherit from my Root class

Strange enough, it seems that you can create a shared_ptr on void and this seems to work correctly, like shown in this example:

class X    {    public:       X() {std::cout << "X::ctor" << std::endl;}       virtual ~X() {std::cout << "X::dtor" << std::endl;}    };  typedef std::shared_ptr<void> SharedVoidPointer;  int main() { X *x = new X(); SharedVoidPointer sp1(x); } 

x is correctly deleted and in a larger experiment I could verify that the shared pointer does indeed what it needs to do (delete x afer the last shared_ptr turns out the light).

Of course this solves my problem, since I can now return data with a SharedVoidPointer data member and be sure that it's correctly cleaned up where it should be.

But is this guaranteed to work in all cases? It clearly works in Visual Studio 2010, but does this also work correctly on other compilers? On other platforms?

like image 236
Patrick Avatar asked Jan 26 '11 16:01

Patrick


People also ask

How does a shared pointer work?

"Shared pointer is a smart pointer (a C++ object wih overloaded operator*() and operator->()) that keeps a pointer to an object and a pointer to a shared reference count. Every time a copy of the smart pointer is made using the copy constructor, the reference count is incremented.

What is the purpose of a void pointer?

The void pointer in C is a pointer that is not associated with any data types. It points to some data location in the storage. This means that it points to the address of variables. It is also called the general purpose pointer.

Why do we use shared pointer?

Use shared_ptr if you want to share ownership of a resource. Many shared_ptr can point to a single resource. shared_ptr maintains reference count for this propose. when all shared_ptr's pointing to resource goes out of scope the resource is destroyed.

Why do we need shared pointers in C++?

Shared pointers in C++ In C++, a shared pointer is one of the smart pointers. The shared pointer maintains a reference count which is incremented when another shared pointer points to the same object. So, when the reference count is equal to zero (i.e., no pointer points to this object), the object is destroyed.


1 Answers

The shared_ptr constructor that you use is actually a constructor template that looks like:

template <typename U> shared_ptr(U* p) { } 

It knows inside of the constructor what the actual type of the pointer is (X) and uses this information to create a functor that can correctly delete the pointer and ensure the correct destructor is called. This functor (called the shared_ptr's "deleter") is usually stored alongside the reference counts used to maintain shared ownership of the object.

Note that this only works if you pass a pointer of the correct type to the shared_ptr constructor. If you had instead said:

SharedVoidPointer sp1(static_cast<void*>(x)); 

then this would not have worked because in the constructor template, U would be void, not X. The behavior would then have been undefined, because you aren't allowed to call delete with a void pointer.

In general, you are safe if you always call new in the construction of a shared_ptr and don't separate the creation of the object (the new) from the taking of ownership of the object (the creation of the shared_ptr).

like image 164
James McNellis Avatar answered Sep 19 '22 06:09

James McNellis