Thread: private overloading of new & delete

  1. #1
    Registered User
    Join Date
    Dec 2002
    Posts
    162

    Question private overloading of new & delete

    Hi

    I have been looking at some custom memory management and I am curious about new/delete overloading. I would like to know if one can limit overloaded new & delete operators to a template specific class (meaning all de-/allocations of all types occurring in the class are using the overloads). And also subject the overloads to the template for that class so different class variants use different overloads, while those overloads do not affect any code outside the given class. To give some more clarity se the example “code” below:

    Code:
    template <class Allocator>
    class Dummy {
    private:
    	
    	// the operators should only be used by the class itself.
    	// assume Allocator is a class supplied with the necessary functions
    
    	void *operator new (size_t size) {
    		return Allocator::allocSomeMemory(size); // call template specific func.
    	}
    
    	void operator delete (void *ptr) {
    		Allocator::deallocTheMemory(ptr); // call template specific function
    	}
    
    public:
    
    	void foobar() {
    		int *x = new int; // calls the overloaded new operator.
    		// please note that the allocated object could be of any type,
    		// including classes
    
    		delete x; // calls the overloaded delete operator
    	}
    };
    Unfortunately this code won’t compile and even if it would the overloads would only be called when de-/allocating the Dummy class, which is not desirable. Any help or ideas are highly appreciated.
    Last edited by Aidman; 04-26-2005 at 04:20 PM.
    We haven't inherited Earth from our parents; instead we have borrowed her from our children - old Indian saying.

  2. #2
    30 Helens Agree neandrake's Avatar
    Join Date
    Jan 2002
    Posts
    640
    I wasn't aware you could overload the new and delete keywords. You are sure you can do this?
    Environment: OS X, GCC / G++
    Codes: Java, C#, C/C++
    AOL IM: neandrake, Email: neandrake (at) gmail (dot) com

  3. #3
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    @neandrake
    Well if you use Visual C++ you may find this useful, if not then you may find it interesting.
    you can also check this

    - Micko
    Last edited by Micko; 04-26-2005 at 05:18 PM.
    Gotta love the "please fix this for me, but I'm not going to tell you which functions we're allowed to use" posts.
    It's like teaching people to walk by first breaking their legs - muppet teachers! - Salem

  4. #4
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Quote Originally Posted by neandrake
    I wasn't aware you could overload the new and delete keywords. You are sure you can do this?
    Just because you aren't aware doesn't mean you can't do it.

    @Aidman
    The first thing I notice is that your template isn't going to do what you think it'll do.

    template<class Allocator>
    class Dummy

    This will take any type (class or not) as a template arguement and name it Allocator. Meaning I could do:
    Dummy<int> and it'd be ok.

    You probably want:

    template<Allocator alloc>
    class Dummy

    Which would take a template arguement of an Allocator object. You might even want to use a default value

    template<Allocator alloc=SomeDefaultAllocator>
    class Dummy

    Ok you say it doesn't compile. How about showing the error messages.

    Instead of using
    new int

    Have you tried:

    Dummy::new int
    ?

  5. #5
    Registered User
    Join Date
    Dec 2002
    Posts
    162
    neandrake:
    Yes it is possible even globally.

    Micko:
    I have tried googling to find an answer but only stumbled across simple how-to overload new and delete for general purposes, nothing in this field. I also check the article and source it seems to be a typical global memory tracer which can't help me. But thanks anyways

    Thantos:
    Thanks for the template syntax correction. The reason why it won't compile is because the overloaded new and delete operators need to be public members. But the main problem is that the overloads are only used for Dummy classes, thus if an outside function would dynamically create a Dummy instance the compiler would call the overloads, which is absolutely not my intention, hence the private access restriction. I tested Dummy::new but the compiler complained: “error C2834: 'operator new' must be globally qualified”
    We haven't inherited Earth from our parents; instead we have borrowed her from our children - old Indian saying.

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Actually, Thantos, your template syntax looks quite invalid to me. That would pass a constant instance of the Allocator class - which is not possible, because only primitives (and not even all of those, at least on some compilers) may be template value arguments.

    And no, you couldn't do Dummy<int>, because then the compiler would try to invoke int's static member function "allocSomeMemory", resulting of course in an error.

    The original syntax is fine, provided that whatever is passed for Allocator actually has those members.

    Aidman: perhaps you'd like to look at how STL allocators work. The bottom line is, no, you can't replace new and delete for arbitraray objects just in your class, but you can call something different.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    I was trying to get at that the what they had probably isn't what they wanted.
    But you are right, it probably needs a reference.

  8. #8
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Haven't achived full results yet (only been working on it for about 20 minutes)

    nd.h
    Code:
    namespace T {
            class Dummy {
                    int *p;
                    public:
                            Dummy();
                            ~Dummy();
                    void DoSomething();
            };
    };
    nd.cpp
    Code:
    #include <iostream>
    #include "nd.h"
    
    namespace T{
            void* operator new(std::size_t t)
            {
                    std::cerr<<"Hello I'm new"<<std::endl;
                    return malloc(t);
            }
            void operator delete(void *ptr)
            {
                    std::cerr<<"Laters"<<std::endl;
                    free(ptr);
            }
            Dummy::Dummy()
            {
                    p = new int;
            }
            Dummy::~Dummy()
            {
                    delete p;
            }
            void Dummy::DoSomething()
            {
                    *p = 5;
                    std::cout<<"p = "<<*p<<std::endl;
            }
    };
    ndmain.cpp
    Code:
    #include <iostream>
    #include "nd.h"
    using std::cout;
    using std::endl;
    int main()
    {
            T::Dummy *d= new T::Dummy;
            d->DoSomething();
            delete d;
            cout<<"Meh?"<<endl;
    }
    Result:
    Hello I'm new
    p = 5
    Meh?
    So its calling the specific new like it's suppose to but for some reason isn't call it's delete.

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    That might be because it calls the new for the T::Dummy you allocate but never delete. Print out the allocation size and make sure Dummy and int have different sizes.

    Seems to be some Koening lookup going on.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #10
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Ok changed the above to:
    nd.h
    Code:
    namespace T {
            class Dummy {
                    int *p;
                    double q;
                    public:
                            Dummy();
                            ~Dummy();
                    void DoSomething();
            };
    };
    nd.cpp
    Code:
    #include <iostream>
    #include "nd.h"
    
    namespace T{
            void* operator new(std::size_t t)
            {
                    std::cerr<<"Hello I'm new"<<std::endl;
                    return malloc(t);
            }
            void operator delete(void *ptr)
            {
                    std::cerr<<"Laters"<<std::endl;
                    free(ptr);
            }
            Dummy::Dummy()
            {
                    p = new int;
            }
            Dummy::~Dummy()
            {
                    T::operator delete( p );
            }
            void Dummy::DoSomething()
            {
                    *p = 5;
                    std::cout<<"p = "<<*p<<std::endl;
            }
    };
    ndmain.cpp
    Code:
    #include <iostream>
    #include "nd.h"
    using std::cout;
    using std::endl;
    int main()
    {
            cout<<"A dummy is: "<<sizeof(T::Dummy)<<" bytes large\nAn int is "<< sizeof(int) <<" bytes large"<<endl;
            T::Dummy *d= new T::Dummy;
            d->DoSomething();
            delete d;
            cout<<"Meh?"<<endl;
    }
    Output:
    A dummy is: 12 bytes large
    An int is 4 bytes large
    Hello I'm new
    p = 5
    Laters
    Meh?

  11. #11
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    You forgot:
    Code:
    void* operator new(std::size_t t)
            {
                    std::cerr<<"Hello I'm new for "<< t << " bytes\n";
                    return malloc(t);
            }
            void operator delete(void *ptr)
            {
                    std::cerr<<"Laters for "<< ptr <<" address.\n";
                    free(ptr);
            }
    The write out the address in main.

    Hmmm... it really allocates the int with the overloaded one. But why not deallocate?

    Code:
    A dummy is: 16 bytes large
    An int is 4 bytes large
    Hello I'm new for 4 bytes
    Dummy: 0x5020a0
    p = 5
    Laters for 0x5020c0.
    Meh?
    (64-bit machine, so int* is 8 bytes.)
    Last edited by CornedBee; 04-28-2005 at 01:58 AM.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  12. #12
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    And the solution to the puzzle comes from the C++ standard, §3.7.3.1:
    An allocation function shall be a class member function or a global
    function; a program is ill-formed if an allocation function is
    declared in a namespace scope other than global scope
    or declared
    static in global scope.
    GCC is incorrect in even compiling this code, and the behaviour is undefined.

    Read also here:
    http://groups-beta.google.com/group/...e&rnum=1&hl=en
    This also mentions that Comeau C++ refuses to compile the code.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  13. #13
    Registered User
    Join Date
    Dec 2002
    Posts
    162
    Nice try Thantos, good idea with the namespace even thought it wasn't supposed to work. However an esential part of my problem would still remain had the solution worked. Letting the class user have the option of choosing allocator for the class ex. via templates.
    We haven't inherited Earth from our parents; instead we have borrowed her from our children - old Indian saying.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Smart pointer class
    By Elysia in forum C++ Programming
    Replies: 63
    Last Post: 11-03-2007, 07:05 AM
  2. MSVC 2003 Debugging delete
    By Bajanine in forum Windows Programming
    Replies: 2
    Last Post: 09-09-2007, 12:15 PM
  3. Overloading new/delete with additional arguments
    By _Elixia_ in forum C++ Programming
    Replies: 0
    Last Post: 11-09-2004, 06:26 AM
  4. Problem need help
    By Srpurdy in forum C++ Programming
    Replies: 1
    Last Post: 07-24-2002, 12:45 PM
  5. Delete Item
    By emilyh in forum Windows Programming
    Replies: 10
    Last Post: 10-03-2001, 09:33 PM