Thread: Reference Counting

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034

    Smile Reference Counting

    I've a program where I'm using pointers all over the place. It's starting to run up to 750mb ram so I need to work on the memory management. Currently I'm not deleting any data after using it (just letting it build up). So my options are either use temporary objects which delete at the end of the scope and copy-construct, or use shared_ptr for auto reference counting, or use an internal reference counter?

    I like the idea of not using pointers, but feel copy-constructing everywhere may be inefficient when I could just pass a pointer or reference. If I pass a reference, the object has to guarantee to exist, but I'm using a lot of asynchronous events, so I can't guarantee that. Even if I keep a list or vector, and want to remove the object, I can't know if it's still required for an asynchronous event out there. So I could have it copied for async, or just use reference counting.

    Which leads me to boost::shared_ptr. It's great and all, common, standard. I'm not really fond (syntactically) of wrapping all my classes with it. I could typedef it, but it still requires you use the wrapped class and the typedef at the same time.

    Seems like many custom implementations use internal reference counts, build into the class or superclass, and from what I can assume a global variable. So the syntax doesn't need to be altered or increase complexity, but you still gain the benefits of memory management. Is there a boost or std way of doing this? or play it safe and stick with shared_ptr?

    P.S. I'm taking out a lot of rows (1000) out of a database, converting them to objects, using them asynchronously, then ignoring them for the rest of the program and fetching 1000 more.

    Thanks, sorry for tl;dr;

    Edit: Okay so I've never seriously used smart pointers, but what's to stop me from doing something like this?

    Code:
    #include <boost/shared_ptr.hpp>
    #include <boost/lexical_cast.hpp>
    
    #include <iostream>
    #include <vector>
    #include <string>
    
    #include <windows.h>
    
    class impl_name
    {
        public: std::string first;
        public: std::string last;
    
        public: impl_name() : first("john"), last("doe")
        {
    		
        }
    
        public: impl_name(std::string const& first, std::string const& last) : first(first), last(last)
        {
    		
        }
    };
    
    class name
    {
        private: boost::shared_ptr<impl_name> data;
    
        public: name() : data(new impl_name())
        {
            
        }
    
        public: name(std::string const& first, std::string const& last) : data(new impl_name(first, last))
        {
           
        }
    
        //copy constructor
        public: name(const name& n) : data(n.data)
        {
            
        }
    
        public: impl_name* operator->()
        {
            return data.get();
        }
    };
    
    void x()
    {
        std::vector<name> names;
    
        Sleep(5000);
    
        std::cout << "Creating..." << std::endl << std::endl;
    
        for(int i = 0; i < 1000000; ++i)
            names.push_back(name("john" + boost::lexical_cast<std::string>(i), "doe"));
    
        Sleep(5000);
    
        std::cout << "Displaying 10..." << std::endl << std::endl;
    
        for(std::vector<name>::iterator i = names.begin(), l = names.end(); i != names.begin() + 10; ++i)
            std::cout << (*i)->first << " " << (*i)->last << std::endl;
    
        std::cout << std::endl;
    
        Sleep(5000);
    
        std::cout << "Erasing..." << std::endl << std::endl;
    
        for(int i = 0; i < 1000000; ++i)
            names.pop_back();
    
        names.empty();
    }
    
    int main()
    {
        x();
    
        std::cin.get();
    }
    Yeah, all I did was wrap the real "impl_name" class with "name" and relay the constructors/operators to the intrusive_ptr of impl_name. That way I can use the class normally, without having to worry about intrusive_ptr or shared_ptr or anything in the usage code. Or is that just asking too much? Seems like all signs point to being REQUIRED to use smart pointers EVERYWHERE in usage code no matter what. It's the only way? Without a garbage collector like Java. I remember seeing source code from Half-Life that overloaded operator new/delete and some other stuff, maybe that was for smart pointers, or maybe just controlling it's memory allocation stack/heap/etc. I dunno.
    Last edited by Dae; 08-13-2009 at 06:30 AM.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  3. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  4. C OpenGL Compiler Error?
    By Matt3000 in forum C Programming
    Replies: 12
    Last Post: 07-07-2006, 04:42 PM
  5. c++ linking problem for x11
    By kron in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2004, 10:18 AM