Jump to content
  • Advertisement
Sign in to follow this  
swinchen

My attempt at a smart pointer.

This topic is 4830 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Ok, so I wasn't happy with other smart pointers so I tried making my own. What does everyone think... does the design make sense? I wanted to store the counter as a reference so I wouldnt run into the same problems that boost::shared_ptr has. extint_ptr stands for external intrusive pointer. Also, I didnt want to have to modify each class that is managed by smart pointers (like you need to with boost::intusive_ptr) I know this code is seriously non-thread safe... which is certainly something I should address.
#include <iostream>

template <class DataType, class CountType>
class extint_ptr
{
  private:
    DataType* m_ptr;
    CountType& m_count;
    
    inline void deref()
    {
      ::std::cout << "deref() AHHH!!!! (RefCnt == " << m_count -1 << ")" << ::std::endl;
      if ( (--m_count <= 0) && m_ptr )
      {
        ::std::cout << "Muahaha, Data freed!" << ::std::endl;
        delete m_ptr;
        m_ptr = NULL;
      }
    }
    
  public:
    extint_ptr(DataType* p_ptr, CountType& p_count) : 
      m_ptr(p_ptr), m_count(p_count) {}
    
    extint_ptr(extint_ptr& p_extint_ptr) : 
      m_ptr( p_extint_ptr.m_ptr ), m_count( ++(p_extint_ptr.m_count) ) {}
    
    ~extint_ptr() { deref(); }
      
    inline DataType& operator*() 
      { if (m_ptr) return *m_ptr; }
    
    inline DataType* operator->() 
      { if (m_ptr) return m_ptr; }
    
    inline bool operator!() const 
      { return !(m_ptr == NULL); }
    
    inline bool operator ==(const extint_ptr &p_extint_ptr) const
      { return ( m_ptr == p_extint_ptr.m_ptr ); }
    
    inline bool operator ==(const DataType* p_ptr) const
      { return ( m_ptr == p_ptr ); }
       
    inline void operator=(const extint_ptr &p_extint_ptr)
    {
      ::std::cout << "operator =" << ::std::endl;
      display();
      if (m_ptr) deref();
      m_ptr = p_extint_ptr.m_ptr;
      m_count = p_extint_ptr.m_count;
      if (m_ptr) ++m_count;
      display();
      ::std::cout << ::std::endl << ::std::endl;     
    }
      
    void display() { ::std::cout << "Data: " << *m_ptr << " RefCnt: " << m_count << ::std::endl; }
};


int main(int argc, char* argv[])
{
  long j = 1;
  long k = 1;
  extint_ptr<int, long> sams(new int, j);
  *sams = 77;
  extint_ptr<int, long> sams2(sams);
  extint_ptr<int, long> bob(new int, k);
  *bob = 1010101010;
  
  bob = sams;
  
  return 0;
}

Share this post


Link to post
Share on other sites
Advertisement
What problems are you imagining boost::shared_ptr has with a pointer to a counter? And of course the fact you have a reference to a counter severely limits the flexibility of the smart pointer. Also your operator= doesn't seem to handle self assignment correctly.

Share this post


Link to post
Share on other sites
why oh why would you want to put the refrence count externally? that's begging for all kinds of scoope related errors not to mention what happens if you somehow end up with multiple diffrent objects sharing the same ref-count var.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
What problems are you imagining boost::shared_ptr has with a pointer to a counter? And of course the fact you have a reference to a counter severely limits the flexibility of the smart pointer. Also your operator= doesn't seem to handle self assignment correctly.


Simple correct solutions is to perform operations in this order:
  • increate "other" ref-count
  • decrease "this" ref-count
  • copy ptr and ref-count

    that would solve the this == other case robustly problem is since your ref-count is a reference you can't change what it points to and the whole scheme will quickly fall togehter (multipe smart pointers sharing object but unaware of their diffrent ref-counts.)

    Share this post


    Link to post
    Share on other sites
    The problem I was having with shared_ptr is that if you return a shared pointer it makes a new reference count, and when the destructor is called it only has 1 count calls delete on your object (no matter how many references you actually have)

    Share this post


    Link to post
    Share on other sites
    Quote:
    Original post by swinchen
    The problem I was having with shared_ptr is that if you return a shared pointer it makes a new reference count, and when the destructor is called it only has 1 count calls delete on your object (no matter how many references you actually have)


    I can't really comprehend what you're talkinb about here. The whole idea with reference counting is to only have your destructor called once hence avoiding needless copies and ensuring that you don't double delete things.

    It sounds to me like you really don't understand how it ought to work. Now the point about boos't newing the reference count, that one i can buy but Im pretty darn sure you can customize that via a user defined allocator if it's giving you speed issues.

    Share this post


    Link to post
    Share on other sites
    Quote:
    Original post by DigitalDelusion
  • increate "other" ref-count
  • decrease "this" ref-count
  • copy ptr and ref-count

    that would solve the this == other case robustly problem is since your ref-count is a reference you can't change what it points to and the whole scheme will quickly fall togehter (multipe smart pointers sharing object but unaware of their diffrent ref-counts.)



  • Like this?

    if (p_extint_ptr.m_ptr) ++(p_extint_ptr.m_count);
    deref();
    m_ptr = p_extint_ptr.m_ptr;
    m_count = p_extint_ptr.m_count;

    I guess I don't see what the problem with my orig. code is.

    Share this post


    Link to post
    Share on other sites
    Quote:

    To create an object using a shared_ptr the "proper" way:

    shared_ptr<myClass> myPointer(new myClass);

    This creates a reference count outside of the class. Any time the myPointer is copied the reference count is incremented. If the reference count drops to zero the object is deleted. The problem here is more than one reference count can exist if you're not careful. If you try to hand out a shared pointer from within the class you might try to do it like this:

    return shared_ptr<myClass>(this);

    This would be very unfortunate because it creates a reference count separate from when new was called to create this object. Now as soon as the pointer you returned goes out of scope (assuming it was not copied) the object will be deleted no matter how many references the original pointer holds.


    Here is the reference: Linky

    Share this post


    Link to post
    Share on other sites
    Quote:
    Original post by swinchen
    I guess I don't see what the problem with my orig. code is.


    Well what happens if p_extint_ptr == this?

    then you first deref the object possibly reducing the ref count to zero and killing the object.

    after that you increate the refcount and take the pointer, problem is that since you killed the object before increasing the refcount it's dead doesn't exist accessing it invokes undefined behaviour.


    Share this post


    Link to post
    Share on other sites
    Quote:
    Original post by swinchen
    ...
    Here is the reference: Linky


    Ok, now I can at least see your problem, but your solution to it is non-working and flawed as outlined above.

    And the idea of handing out pointers to itself kinda smells if you ask me, how did a client get a raw pointer to the object to begin with? If it's reference counted shoulnd't clients be able to see the shared_ptr and work with that?

    Share this post


    Link to post
    Share on other sites
    Sign in to follow this  

    • Advertisement
    ×

    Important Information

    By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

    We are the game development community.

    Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

    Sign me up!