Thread: Use Count smart pointers. Need clarification

  1. #1
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446

    Use Count smart pointers. Need clarification

    This discussion on memory leaks reminded me of something I wanted to ask a couple of days ago.

    I've recently read on the Use Count technique to manage pointer data members. However, it confused me. Not so much how they are implemented, but more the why they are implemented.

    And this is why; Assuming Ptr_class to be a class object that has a single pointer data member and that implements Use Count to manage this pointer...

    Code:
        int *value = new int(6);
        {
             Ptr_class bla(value); 
        }
        std::cout << *value << std::endl;
    The output is undefined. As soon as bla gets out of scope, the destructors of both bla and the use count class will make sure bla gets destroyed, but also that the free store gets freed.

    1.
    Why do I want this? At first glance, this seems to me an intrusive behavior of bla, considering that value's lifespan becomes dependant on Ptr_class. The owner of the free store object is the class user, not the class implementor.

    2.
    This technique forces any object of the Ptr_class to be defined based on the free store. If value is not defined on the free store, the above code throws a compile-time error. Doesn't this technique limit my use of this class?

    3.
    With each new pointer member being defined in Ptr_Class, the Use Count class needs to define another counter and another pointer. Isn't this excessive in terms of memory usage?

    4.
    With each new pointer member, the class copy control becomes increasingly bloated with code. Is this technique efficient?

    I confess, Use Count didn't suit my fancy. But maybe I'm not seeing this correctly.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    1. The idea is to store the value immediately in bla. At that point, the lifetime of value is tied to bla (or if bla is a referenced counted smart pointer, it is tied to all remaining instances that refer to value). That is the point. You want the lifetime of the pointer tied to an object so that you know that the memory will be freed and destructors called when bla goes out of scope (or all copies if Ptr_class is like shared_ptr).

    2. No. The point of the smart pointer is to mimic the behavior of a local variable. If the variable is on the stack, then its destructor will be called automatically when it goes out of scope. The smart pointer allows that behavior to occur with heap allocated objects as well.

    3. I'm not sure what you refer to with Use Count, but there is a tradeoff with reference counted smart pointers. Usually, though, the negative effects of extra memory usage are minimal when compared to the entire program or module. For lightweight objects like int, it doesn't make sense to use a referenced counted smart pointer, since the size of the data held is so small. For larger classes, though, it is less of an issue.

    4. Again, I don't know what Use Count is you are referring to. I've been assuming you are talking about reference counted smart pointers like std::tr1::shared_ptr. The answer in that case is the same as for #3.

  3. #3
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    the Use Count technique I learned is implemented this way,

    I removed the accessor members for an easier reading. But basically, for the class Ptr_class that implements a pointer, a friend class is created that implements the pointer management.

    Code:
    class Use_count {
        friend class Ptr_class;
    
        Use_count(int* p): ip(p), counter(1) {};
        ~Use_count() { delete ip; }
    
        int* ip;
        size_t counter;
    };
    
    class Ptr_class {
    public:
        Ptr_class(int* p): ptr(new Use_count(p)) {}
        Ptr_class(const Ptr_class &obj):ptr(obj.ptr) { ++ptr->counter; }
        ~Ptr_class() { if(--ptr->counter == 0) delete ptr; }
    
        Ptr_class& operator=(const Ptr_class&);
        
    private:
        Use_count* ptr;
    };
    
    Ptr_class& Ptr_class::operator=(const Ptr_class &obj) {
        ++obj.ptr->counter;
        if(--ptr->counter == 0)
            delete ptr;
        ptr = obj.ptr;
        return *this;
    }
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  4. #4
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Quote Originally Posted by Daved
    1. The idea is to store the value immediately in bla. At that point, the lifetime of value is tied to bla (or if bla is a referenced counted smart pointer, it is tied to all remaining instances that refer to value). That is the point. You want the lifetime of the pointer tied to an object so that you know that the memory will be freed and destructors called when bla goes out of scope (or all copies if Ptr_class is like shared_ptr).

    2. No. The point of the smart pointer is to mimic the behavior of a local variable. If the variable is on the stack, then its destructor will be called automatically when it goes out of scope. The smart pointer allows that behavior to occur with heap allocated objects as well.
    Ok, Daved. I got it. I wasn't see this through that pespective.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  5. #5
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    This idea, known as RAII, is an extremely important and powerful one in C++. If you can design your code and classes with RAII in mind, you'll have much safer and robust code.

  6. #6
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    However, and if I understood correctly, I was focusing on the class implementation, assuming this technique to be a way to manage pointer members, when in fact this technique is more meant to manage resource allocation through the use of a class that implements a pointer, correct?
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  7. #7
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    No. I was still wrong. I think I understand now from what I was reading on RAII and Use Count on the web after you gave me a few hints on how to search for more info.

    The idea is instead to make sure that the object to which the data member points stays "alive" for at least as long as the lifespan of the data member pointer.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  8. #8
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    Mario, your design is what's know as an Intrusive Pointer. Have a look at the design of the boost::shared_ptr. It's a template that can be used with any class that requires no modification to the class.
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  9. #9
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    I will... thanks, Chaos.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting number
    By Leslie in forum C Programming
    Replies: 8
    Last Post: 05-20-2009, 04:23 AM
  2. Smart pointer questions
    By Elysia in forum C++ Programming
    Replies: 3
    Last Post: 03-13-2009, 01:54 PM
  3. Variable pointers and function pointers
    By Luciferek in forum C++ Programming
    Replies: 11
    Last Post: 08-02-2008, 02:04 AM
  4. Ban pointers or references on classes?
    By Elysia in forum C++ Programming
    Replies: 89
    Last Post: 10-30-2007, 03:20 AM
  5. Staticly Bound Member Function Pointers
    By Polymorphic OOP in forum C++ Programming
    Replies: 29
    Last Post: 11-28-2002, 01:18 PM