CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Aug 2000
    Posts
    1,471

    Help with overloading operator delete

    Here is what I did,
    Code:
    class A
    {
    public:
    	A()
    	{
    		p1 = new int(1);
    		p2 = new int(2);
    	}
    
    private:
    	int* p1;
    	int* p2;
    };
    
    void* operator new(size_t size, int dummy)
    {
    	void* p = malloc(size);
    	
    	return p;
    }
    
    void operator delete(void* ptr, int dummy)
    {
    	free(ptr);
    }
    
    #define new new(0)
    #define delete delete(0)
    
    int main() 
    {
    	A* pA = new A;
    
    	delete pA;
    	return 0;
    }
    But it doesn't compile. There is an error "error C2541: 'delete' : cannot delete objects that are not pointers". What is wrong with my code? Thanks for your inputs.

  2. #2
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: Help with overloading operator delete

    Quote Originally Posted by dullboy View Post
    Code:
    #define new new(0)
    #define delete delete(0)
    What is this supposed to do?
    Your main function expands to this after preprocessing.
    Code:
    int main() 
    {
    	A* pA = new(0) A;
    
    	delete(0) pA;
    	return 0;
    }
    That means you are doing placement new at memory address 0. That will likely crash your program. Then the delete is called on an int. Hence, the compiler error.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  3. #3
    Join Date
    Aug 2000
    Posts
    1,471

    Re: Help with overloading operator delete

    I tried to overload the operator new and operator delete as,
    Code:
    void* operator new(size_t size, int dummy);
    void operator delete(void* ptr, int dummy);
    Here the int dummy is used to simply distinguish default operrator new and operator delete. So A* pA = new(0) A will call my operator new instead of placement new. In addition, why'd you think "the delete is called on an int"?
    Here again delete(0) pA is supposed to call my operator delete. Any ideas? Thank you very much!
    Quote Originally Posted by D_Drmmr View Post
    What is this supposed to do?
    Your main function expands to this after preprocessing.
    Code:
    int main() 
    {
    	A* pA = new(0) A;
    
    	delete(0) pA;
    	return 0;
    }
    That means you are doing placement new at memory address 0. That will likely crash your program. Then the delete is called on an int. Hence, the compiler error.

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Help with overloading operator delete

    Quote Originally Posted by dullboy View Post
    I tried to overload the operator new and operator delete as,
    Code:
    void* operator new(size_t size, int dummy);
    void operator delete(void* ptr, int dummy);
    Here the int dummy is used to simply distinguish default operrator new and operator delete. So A* pA = new(0) A will call my operator new instead of placement new. In addition, why'd you think "the delete is called on an int"?
    Here again delete(0) pA is supposed to call my operator delete. Any ideas? Thank you very much!
    So to use an overloaded delete operator, you have to use different syntax to invoke "delete"? Does that sound right to you? If that were the case, then C++ programmers would be in a mess changing all of their code that happens to use a library's implementation of "delete". Of course, this isn't the case.

    Your code doesn't compile with the on-line Comeau compiler. First, you need to include <cstdlib>, but second, the error from that compiler is almost exactly the same as the one from Visual C++. So your observations as to what you want to do is incorrect.

    The compiler sees that you are trying to delete an int -- plain and simple. The way you distinguish your overloaded operator delete from the global delete is that when you want to invoke the global delete, you use the scope resolution operator:
    Code:
    ::delete p; // where p is a pointer to some type
    If you want to call your overloaded version, then you don't use the scope resolution operator. That other stuff you've added to your delete operator is not even used and does nothing. Again, two different compilers report the same error.

    Here is the proper way to overload new and delete:
    Code:
    #include <cstdlib>
    #include <new>
    class A
    {
    public:
        A()
        {
            p1 = new int(1);
            p2 = new int(2);
        }
    
    private:
        int* p1;
        int* p2;
    };
    
    void* operator new(size_t size)
    {
        void* p = malloc(size);
    
        return p;
    }
    
    void operator delete(void* ptr)
    {
        free(ptr);
    }
    
    int main() 
    {
        A* pA = new A;
    
        delete pA;
        return 0;
    }
    Run this using the debugger. You will now see that your overloaded versions are called.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; June 20th, 2010 at 11:28 AM.

  5. #5
    Join Date
    Aug 2000
    Posts
    1,471

    Re: Help with overloading operator delete

    Thanks for your response. It turns out to be very helpful. But I still have a question here. Please check the following code first.
    Code:
    class A
    {
    public:
    	A()
    	{
    		p1 = new int(1);
    		p2 = new int(2);
    	}
    
    private:
    	int* p1;
    	int* p2;
    };
    
    void* operator new(size_t size, int dummy)
    {
    	void* p = malloc(size);
    	
    	return p;
    }
    
    void operator delete(void* ptr)
    {
    	free(ptr);
    }
    
    #define new new(0)
    
    int main() 
    {
    	A* pA = new A;
    
    	delete pA;
    	return 0;
    }
    This code compiles and works just fine. So you can see I can add one more parameter to operator new but it looks like I CAN'T add one more parameter to operator delete. Why? Thanks for your inputs.
    Quote Originally Posted by Paul McKenzie View Post
    So to use an overloaded delete operator, you have to use different syntax to invoke "delete"? Does that sound right to you? If that were the case, then C++ programmers would be in a mess changing all of their code that happens to use a library's implementation of "delete". Of course, this isn't the case.

    Your code doesn't compile with the on-line Comeau compiler. First, you need to include <cstdlib>, but second, the error from that compiler is almost exactly the same as the one from Visual C++. So your observations as to what you want to do is incorrect.

    The compiler sees that you are trying to delete an int -- plain and simple. The way you distinguish your overloaded operator delete from the global delete is that when you want to invoke the global delete, you use the scope resolution operator:
    Code:
    ::delete p; // where p is a pointer to some type
    If you want to call your overloaded version, then you don't use the scope resolution operator. That other stuff you've added to your delete operator is not even used and does nothing. Again, two different compilers report the same error.

    Here is the proper way to overload new and delete:
    Code:
    #include <cstdlib>
    #include <new>
    class A
    {
    public:
        A()
        {
            p1 = new int(1);
            p2 = new int(2);
        }
    
    private:
        int* p1;
        int* p2;
    };
    
    void* operator new(size_t size)
    {
        void* p = malloc(size);
    
        return p;
    }
    
    void operator delete(void* ptr)
    {
        free(ptr);
    }
    
    int main() 
    {
        A* pA = new A;
    
        delete pA;
        return 0;
    }
    Run this using the debugger. You will now see that your overloaded versions are called.

    Regards,

    Paul McKenzie

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Help with overloading operator delete

    Quote Originally Posted by dullboy View Post
    This code compiles and works just fine. So you can see I can add one more parameter to operator new but it looks like I CAN'T add one more parameter to operator delete. Why? Thanks for your inputs.
    http://www.cplusplus.com/reference/s...0delete%5B%5D/

    Regards,

    Paul McKenzie

  7. #7
    Join Date
    Aug 2000
    Posts
    1,471

    Re: Help with overloading operator delete

    Would you please explain it a little bit more? I couldn't relate my original question to the reference. Thanks for your inputs.
    Quote Originally Posted by Paul McKenzie View Post

  8. #8
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Help with overloading operator delete

    Quote Originally Posted by dullboy View Post
    Would you please explain it a little bit more? I couldn't relate my original question to the reference. Thanks for your inputs.
    The explanation is that your code is invalid. The reference shows you what is overrideable and how to override using the proper function signature..

    If a reference tells you "to do x, this is what is done", you don't try and do something different, hoping it works. Where in the reference do you see an "int" as a second parameter to operator delete?

    The same reference is here -- it doesn't matter if it's delete[] or delete, they must be overridden using the proper signatures, otherwise they're bogus.

    http://www.cplusplus.com/reference/s...&#37;20delete/

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; June 20th, 2010 at 04:28 PM.

  9. #9
    Join Date
    Aug 2000
    Posts
    1,471

    Re: Help with overloading operator delete

    If what you claimed is true, how can you explain I can add an "int" as a second parameter to operator new? In the reference I don't see an "int" as a second parameter to operator new either. Thanks for your inputs.
    Quote Originally Posted by Paul McKenzie View Post
    The explanation is that your code is invalid. The reference shows you what is overrideable and how to override using the proper function signature..

    If a reference tells you "to do x, this is what is done", you don't try and do something different, hoping it works. Where in the reference do you see an "int" as a second parameter to operator delete?

    The same reference is here -- it doesn't matter if it's delete[] or delete, they must be overridden using the proper signatures, otherwise they're bogus.

    http://www.cplusplus.com/reference/s...ator%20delete/

    Regards,

    Paul McKenzie

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Help with overloading operator delete

    Quote Originally Posted by dullboy View Post
    If what you claimed is true, how can you explain I can add an "int" as a second parameter to operator new? In the reference I don't see an "int" as a second parameter to operator new either. Thanks for your inputs.
    Because "new" is not "delete". What makes you believe they follow the same rules?

    The operator new() you are doing by chance is called placement-new. There is no such thing as "placement-delete".

    http://www.parashift.com/c++-faq-lit...html#faq-11.10

    And you were already told this by D Drmmr:
    That means you are doing placement new at memory address 0. That will likely crash your program. Then the delete is called on an int. Hence, the compiler error.
    So the "new" you were doing is not what you thought it was doing. That "int" parameter is an address where you will place the constructed object -- it has nothing to do with "distinguishing" between the global new and an overloaded new, but you stumbled onto the placement-new syntax without knowing what it really means.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; June 22nd, 2010 at 11:11 AM.

  11. #11
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Help with overloading operator delete

    To append on Paul.

    The 'dummy' you're using in your new operator does actually serve a purpose (as a placement address). However, you are ignoring the placement, and just allocating memory of your own.

    If you were to use your A class in container or template class that makes use of placement new, your class would fail.

    To further proove that you can't just do 'anything' with the new operators: Try changing the 'int' in the operator to something else, say a class of your own.

    If your assumption is true, than you should be able to put just about anything in there as 'dummy' parameter simply to distinguish your new from the global new. You'll find however that it does indeed ONLY work with an int. And that's because you've found a very specific case of a new to overload.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured