CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 27
  1. #1
    Join Date
    Mar 2006
    Posts
    33

    overwriting new and delete

    Hi all,

    I am overriding new and delete for some c++ classes.
    I am wondering if its also ok to override new and delete in the same way for structures.

    i.e. when declaring a struct, redefine the operator new and delete for that struct

    or

    Is it only possible to override new and delete that structures will end up using by overriding global new and delete.

    Cheers,
    Seany.

  2. #2
    Join Date
    Feb 2006
    Location
    London
    Posts
    238

    Re: overwriting new and delete

    struct is almost equivalent to class. So overwriting operator new for a struct will give the same effect as overwriting one for a class.

  3. #3
    Join Date
    Feb 2002
    Posts
    4,640

    Re: overwriting new and delete

    IIRC, in C++ a struct is the same as a class, with all members 'public' by default. As a matter of fact:
    Code:
    #include <iostream>
    
    struct SomeStruct
    {
       SomeStruct() : m_AnInt(0)  {}
    
       int GetMe() { return m_AnInt; }
       void ModMe()   { UpdateMe(); }
    
    private:
       void UpdateMe()   { ++m_AnInt; }
       int m_AnInt;
    };
    
    int main(/*int argc, char *argv[]*/)
    {
       SomeStruct testStruct;
       std::cout << "My test is currently:  " << testStruct.GetMe() << std::endl;
    
       testStruct.ModMe();
       testStruct.ModMe();
       testStruct.ModMe();
    
       std::cout << "My test is now:  " << testStruct.GetMe() << std::endl;
    
       return 0;
    }
    Should output:
    My test is currently: 0
    My test is now: 3
    But, if I try to access 'UpdateMe' directly, I get:
    d:\Projects\JunkConsole\test.cpp(23) : error C2248: 'SomeStruct::UpdateMe' : cannot access private member declared in class 'SomeStruct'
    Viggy

  4. #4
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: overwriting new and delete

    inheritance is also by default private for a class and public for a struct.

    This can be quite confusing but I'm pretty sure it's this way round:
    Code:
    struct A{};
    
    class B : A{}; // private
    
    struct C : B{}; // public

  5. #5
    Join Date
    Feb 2006
    Location
    London
    Posts
    238

    Re: overwriting new and delete

    Quote Originally Posted by MrViggy
    IIRC, in C++ a struct is the same as a class, with all members 'public' by default.
    Don't you contradict yourself?

  6. #6
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: overwriting new and delete

    Quote Originally Posted by DragForce
    Don't you contradict yourself?
    It is a syntactic difference. Only the default access rights to members.
    Everything is exactly the same...

    So, a struct is a class and a class is a struct.
    But a class definition is not exactly (but very similar) the same than a struct definition.
    "inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.
    Club of lovers of the C++ typecasts cute syntax: Only recorded member.

    Out of memory happens! Handle it properly!
    Say no to g_new()!

  7. #7
    Join Date
    Sep 2004
    Location
    A Planet Called Earth... :-)
    Posts
    835

    Re: overwriting new and delete

    Quote Originally Posted by SuperKoko
    But a class definition is not exactly (but very similar) the same than a struct definition.
    Did not folllow this ??
    C++ program ran... C++ program crashed... C++ programmer quit !!

    Regards

    Shaq

  8. #8
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: overwriting new and delete

    Quote Originally Posted by Vedam Shashank
    Did not folllow this ??
    A class is a struct and a struct is a class:

    Code:
    struct TObject; // declaration
    
    class TObject // definition
    {
    int x; // here, x is private
    };
    
    int main()
    {
    struct TObject x;
    class TObject y;
    }
    That code should work.

    However, using the struct-keyword instead of the class-keyword is a bit different when defining a class:
    Code:
    struct TObject; // declaration
    
    struct TObject // definition
    {
    int x; // here x is public
    };
    
    int main()
    {
    struct TObject x;
    class TObject y;
    }
    "inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.
    Club of lovers of the C++ typecasts cute syntax: Only recorded member.

    Out of memory happens! Handle it properly!
    Say no to g_new()!

  9. #9
    Join Date
    Mar 2006
    Posts
    33

    Re: overwriting new and delete

    Jeez guys!

    Ye were havin fun. My post has turned from operator overloading to misunderstandings in textual descriptions between classes and structs.
    Thanks for the posts anyway, it made me laugh!

    Dragforce confirmed what I was looking for in the first post.
    It just means I have a problem. I have defined new and delete in my struct to override the allocation mechanism and when I debug into it, my definition of operator new gets called but when I delete my struct the system delete gets called. This is a problem.

    i.e.

    struct test
    {
    void* operator new( size_t sz )
    {
    ....
    }

    void operator delete( void* ptr )
    {
    .....
    }

    cList<int> m_nodes;
    cList<float> m_values;
    };

    How I use it

    test* a = new test;
    ....
    delete test;

    Are there situations where my overload of operator new would be called but when delete is called it calls the system delete. Does it not recognize the definition. Note: Code compiles and runs without error.

  10. #10
    Join Date
    Feb 2005
    Location
    "The Capital"
    Posts
    5,306

    Re: overwriting new and delete

    I suspect the void pointer to your overloaded delete operator:
    Code:
    void operator delete( void* ptr  )
    This could also be disastrous depending upon what is done in the inside. You should not call delete on a void* - delete (or overloaded delete) must be called on the same type whose allocation was done with new (or overloaded new). Hope this helps.

    By the way, why do you need to specialize these operators for your class and structs? Regards.

  11. #11
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: overwriting new and delete

    Quote Originally Posted by exterminator
    I suspect the void pointer to your overloaded delete operator:
    void* is the correct parameter!

    operator delete frees raw memory.
    "inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.
    Club of lovers of the C++ typecasts cute syntax: Only recorded member.

    Out of memory happens! Handle it properly!
    Say no to g_new()!

  12. #12
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: overwriting new and delete

    seany : try that code:
    Code:
    #include <cstdlib>
    #include <iostream>
    
     struct test
     {
     void* operator new( size_t sz )
     {
     std::cout << "[new "<<sz<<"]";
     return std::malloc(sz);
     }
    
     void operator delete( void* ptr )
     {
     std::cout << "[delete @" << ptr << "]";
     std::free(ptr);
     }
     };
    
    int main()
    {
    test* p=new test;
    delete p;
    }
    It works as expected with GCC (assuming malloc doesn't fail), and should work with your compiler.

    If your compiler is buggy on that code, then, try to add a second size_t parameter to operator delete.
    Code:
     void operator delete( void* ptr , std::size_t)
     {
     std::cout << "[delete @" << ptr << "]";
     std::free(ptr);
     }
    Also, in order to be more explicit for human people, and perhaps for the compiler if it is not ISO compliant, I suggest you explicit the static keyword for these operators:
    Code:
    #include <cstdlib>
    #include <iostream>
    
     struct test
     {
     static void* operator new( size_t sz )
     {
     std::cout << "[new "<<sz<<"]";
     return std::malloc(sz);
     }
    
     static void operator delete( void* ptr, std::size_t )
     {
     std::cout << "[delete @" << ptr << "]";
     std::free(ptr);
     }
     };
    
    int main()
    {
    test* p=new test;
    delete p;
    }
    "inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.
    Club of lovers of the C++ typecasts cute syntax: Only recorded member.

    Out of memory happens! Handle it properly!
    Say no to g_new()!

  13. #13
    Join Date
    Mar 2006
    Posts
    33

    Re: overwriting new and delete

    Guys,

    This is not a problem with my code but with an external library........

    Guess what it is......

    ATL

    ATL overrides new and delete also.

    ATL has a different definition of operator new to the standard new operator and delete is the same definition in ATL as the standard library delete.
    So......the code is allocating fine using my new operator as it matches the parameter list I pass in. The delete however is the same as the ATL definition, so when I delete anything, the bloody ATL delete operator gets used.

    Without changing the definition of my operators, is there any way to get ATL to turn off its operator overloading. ATL is needed, I just want none of its memory support.

    A question above, asked why I override the new and delete.
    New and delete can be overridden when you wish to use your own memory allocator or if you need to perform analysis on the memory use of your program, so you can attach debug to allocations etc.

    There is no rule in C++ which states do not use it, you just need to know how to use it properly. Unfortunately, some other libraries like the same idea.

  14. #14
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: overwriting new and delete

    Quote Originally Posted by seany
    ATL has a different definition of operator new to the standard new operator and delete is the same definition in ATL as the standard library delete.
    ATL uses a custom operator new, but uses the standard delete?

    Your problem may be due to the fact that you inherit from a class having no virtual destructor, but an overloaded operator delete, and you delete a derived class via a base class pointer.
    Anyway, behaviour is undefined : With or without operator overloading.

    If you derive from a class having no virtual destructor, you can define a virtual destructor into your derived class, and use this class as a root for all your class hierarchy, and then, you'll delete all your objects via a pointer to your root class, which is correct!

    Note : If the destructor is virtual, the correct operator delete will be called.
    operator delete, if the destructor is virtual, can be seen as a static virtual function invoked after the death of the class.

    In the worst case, your new "root class" will be trivial:
    Code:
    class MyRootClass: public TheClassWhichHasNoVirtualDestructor
    {
    public:
    virtual ~MyRootClass() {}
    // nothing more here
    };
    "inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.
    Club of lovers of the C++ typecasts cute syntax: Only recorded member.

    Out of memory happens! Handle it properly!
    Say no to g_new()!

  15. #15
    Join Date
    Feb 2005
    Location
    "The Capital"
    Posts
    5,306

    Re: overwriting new and delete

    SuperKoko, thanks for correcting me.

    Seany - basically the type being used with the delete expression should determine which delete is to be called. If the correct one is not being called you can try explicitly calling the corresponding delete for the used new expression. But before that can be done, can you please post the version of new and delete that you are having problem with?

    For the array form of operator delete - even when the destructor is defined virtual - the behaviour is undefined if the static type of the object and dynamic type are different (i.e. in a hierarchy). From the standards:
    Quote Originally Posted by 12.5 Free store para 11
    Code:
    struct B {
            virtual ~B();
            void operator delete[](void*, size_t);
    };
    struct D : B {
            void operator delete[](void*, size_t);
    };
    void f(int i)
    {
            D* dp = new D[i];
            delete [] dp; // uses D::operator delete[](void*, size_t)
            B* bp = new D[i];
            delete[] bp; // undefined behavior
    }
    Last edited by exterminator; April 6th, 2006 at 10:32 AM.

Page 1 of 2 12 LastLast

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