Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX

By submitting your information, you agree that devx.com may send you DevX offers via email, phone and text message, as well as email offers about other products and services that DevX believes may be of interest to you. DevX will process your information in accordance with the Quinstreet Privacy Policy.


Automate Resource Management with shared_ptr-2 : Page 2




Application Security Testing: An Integral Part of DevOps

Presenting the Problem
A typical smart pointer wraps a raw pointer to a dynamically allocated object and overloads the operators -> and *. The responsibility for deleting the pointer is delegated to the smart pointer's destructor, thus freeing you from manual—and bug-prone—memory management. The problem, however, is that auto_ptr, the only smart pointer class available in C++98, has peculiar copy and assignment semantics. When you assign an auto_ptr x to another auto_ptr y, not only is the target object modified (as expected) but so is the source object, which becomes null. This behavior makes auto_ptr incompatible with STL containers and algorithms. Let's see how shared_ptr solves this problem.

Author's Note: To use shared_ptr you need to download its sources from Boost. Notice that this Solution adheres to the official TR1 Draft Proposal, which differs slightly from boost::shared_ptr.

Construction and Initialization
shared_ptr's default constructor creates what is known as an empty smart pointer, i.e., an object whose pointer is null. You can assign a valid pointer to it later:

class Foo{ int x; public: explicit Foo(int val=0) :x(val) {} void do_something() {/*..*/} int show_x() const {std::cout<< x<<std::endl; } }; #include <memory> //for shared_ptr using std::tr1::shared_ptr; int main() { shared_ptr<Foo> pf; //pf is an empty shared_ptr //bind a "live" pointer to pf pf=new Foo; pf->do_mesomething(); //using shared_ptr's overloaded -> (*pf).show_x();//using shared_ptr's overloaded * }//pf's destructor called here, destroying Foo

shared_ptr defines a conversion operator to bool. This is useful for testing whether the shared_ptr is empty. To access the raw pointer directly, call get():

if (pf) { //ensure that pf isn't empty before calling get Foo *palias = pf.get(); }

The second shared_ptr constructor takes a pointer to a dynamically allocated object and an optional deleter. The following example defines a deleter and passes its address to shared_ptr's constructor:

void my_deleter(Foo *ptr) { delete ptr; std::cout<< "using custom deleter" <<std::endl; } shared_ptr<Foo> pf (new Foo, my_deleter);

A deleter can be any callable entity: a free function, a function object, etc. When a user-defined deleter d is provided, shared_ptr's destructor calls:


Instead of deleting ptr directly. A custom deleter enables you to bind shared_ptr to a pointer that was allocated in a different DLL, for example.

Certain resources such as file descriptors, synchronization objects, and device contexts require that a special API function be called to release them. Using a custom deleter, shared_ptr can manage such resources elegantly. In the following example, shared_ptr holds a mutex pointer obtained from an API function. When the shared_ptr object is destroyed, the release_mutex() function is called automatically:

//API functions for acquiring and releasing a mutex mutex_t* get_mutex(pid_t pid); int release_mutex(mutex_t* pmx); shared_ptr <mutex_t> pmutex (get_mutex(mypid), release_mutex);

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date