Sign in to follow this  
  • entries
    72
  • comments
    104
  • views
    45408

As smart as any pointer.

Sign in to follow this  

148 views

Yesterday i finally managed to track down a memory bug that was getting on my nerves. It turned out that objects of a certain class were being copied around inside a container, which worked fine until I added a member that pointed to heap memory. The default copy constructor caused many objects to point to the same memory and when it was time to delete my app went down hard. At that point I solved it by simply letting the container contain pointers instead of copies since it made more sense anyway not to have multiple copies of such objects.

In the long run I needed to make sure this wouldn't happen again so, since I didn't want to implement copy constructors and assignment operators for every class that has dynamically allocated members, I decided to make a smart pointer. The HeapPtr (perhaps not the best name) template does nothing more really than making sure that two such pointers doesn't address the same memory. When copy constructed it allocates a copy of the pointed object. The same goes for assignment after deallocating any previous memory. This way my classes can use dynamically allocated members without having to define a copy constructor or an assignment operator. Slick!

template<class T>
class HeapPtr {

private:
T *ptr;

void free( );

public:
HeapPtr( );
HeapPtr( const HeapPtr &o );
HeapPtr( const T *p );
~HeapPtr( );

HeapPtr &operator =( const HeapPtr &o );
HeapPtr &operator =( const T *p );

T &operator *( ) const { return *ptr; }
T *operator ->( ) const { return ptr; }

operator T*( ) const { return ptr; }
bool operator !( ) const { return !ptr; }
bool operator ==( const HeapPtr &o ) const { return ( ptr == o.ptr ); }
bool operator ==( const T *p ) const { return ( ptr == p ); }
};

template<class T>
HeapPtr::HeapPtr( ) {
ptr = 0;
}

template<class T>
HeapPtr::HeapPtr( const HeapPtr &o ) {
// Allocate a copy if the reference object points to anything.
ptr = ( o.ptr ) ? new T( *o.ptr ) : 0;
}

template<class T>
HeapPtr::HeapPtr( const T *p ) {
ptr = ( p ) ? new T( *p ) : 0;
}

template<class T>
HeapPtr::~HeapPtr( ) {
free( );
}

template<class T>
HeapPtr &HeapPtr::operator =( const HeapPtr &o ) {
free( );
// Allocate a copy if the reference object points to anything.
ptr = ( o.ptr ) ? new T( *o.ptr ) : 0;
}

template<class T>
HeapPtr &HeapPtr::operator =( const T *p ) {
free( );
ptr = ( p ) ? new T( *p ) : 0;
}

template<class T>
void HeapPtr::free( ) {
if ( ptr ) {
delete ptr;
ptr = 0;
}
}
Sign in to follow this  


0 Comments


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now