Corresponding forms of new and delete

Discussion in 'C++' started by Dave, Oct 20, 2003.

  1. Dave

    Dave Guest

    Hello all,

    In the code below, I see the following output:

    base::eek:perator new(size_t, int)
    base::base()
    base::~base()
    base::eek:perator delete(void *)

    In the case of an exception being thrown during construction, a form of
    delete with a signature that corresponds to that of the "new" being used
    will be called. However, during a "normal" deallocation, there is no way to
    know which version of "new" was previously used, so the usual deallocation
    routine is used (I hope I'm using the term "usual" properly here). This is
    demonstrated in the output shown above.

    When the statement "delete ptr;" is reached, is there a way to cause it to
    use "operator delete(void*, int)" as the underlying deallocation routine
    rather than "operator delete(void *)"? After all, the usual dellaocation
    routine may not do what's right given that the memory was not allocated with
    the usual allocation routine! (Again, I hope I'm using the term "usual"
    properly.)

    I am aware that I could do the following in place of "delete ptr;":

    ptr->~base();
    base::eek:perator delete(ptr, 243);

    However, the point of this article is to see if there is a way to do what I
    desire without using explicit calls to the destructor or "operator delete".

    Thanks,
    Dave


    #include <iostream>

    using namespace std;

    struct base
    {
    base()
    {
    cout << "base::base()" << endl;
    }

    ~base()
    {
    cout << "base::~base()" << endl;
    }

    void *operator new(size_t size)
    {
    cout << "base::eek:perator new(size_t)" << endl;
    return ::eek:perator new(size);
    }

    void *operator new(size_t size, int)
    {
    cout << "base::eek:perator new(size_t, int)" << endl;
    return ::eek:perator new(size);
    }

    void operator delete(void *ptr)
    {
    cout << "base::eek:perator delete(void *)" << endl;
    ::eek:perator delete(ptr);
    }

    void operator delete(void *ptr, int)
    {
    cout << "base::eek:perator delete(void *, int)" << endl;
    ::eek:perator delete(ptr);
    }
    };

    int main()
    {
    base *ptr(new(243) base);

    delete ptr;

    return 0;
    }



    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
     
    Dave, Oct 20, 2003
    #1
    1. Advertising

  2. Hi,
    In comp.lang.c++.moderated Dave <> wrote:

    > Hello all,


    > In the code below, I see the following output:


    > base::eek:perator new(size_t, int)
    > base::base()
    > base::~base()
    > base::eek:perator delete(void *)


    > When the statement "delete ptr;" is reached, is there a way to cause it to
    > use "operator delete(void*, int)" as the underlying deallocation routine
    > rather than "operator delete(void *)"?


    Short and simple: No.

    If you require additional environment information for the memory allocation
    or deallocation, you have to store it along with the memory allocated.

    A typical solution would be to allocate "one additional int" along with the
    requested memory and store the "int argument" of new in there. Then, in
    the delete operator, you need to extract it from there.

    Basically (unchecked source, so keep care!)

    void *base::eek:perator new(size_t s, int x)
    {
    size_t *mem = (size_t *)malloc(s + sizeof(int));
    *mem = x;
    return mem+1;
    }

    void base::eek:perator delete(void *mem)
    {
    size_t *mymem = (size_t *)mem;
    int x = mymem[-1]; // extract private information.
    free(mymem-1);
    }

    The above code still requires work for architectures where the alignment
    restrictions for size_t are insufficient for some other objects, but it
    should give you the general idea how to solve this problem.

    Greetings,
    Thomas


    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
     
    Thomas Richter, Oct 21, 2003
    #2
    1. Advertising

  3. Dave

    Dhruv Guest

    On Mon, 20 Oct 2003 17:11:51 -0400, Dave wrote:

    >
    > Hello all,
    >
    > In the code below, I see the following output:
    >
    > base::eek:perator new(size_t, int)
    > base::base()
    > base::~base()
    > base::eek:perator delete(void *)
    >
    > In the case of an exception being thrown during construction, a form

    of
    > delete with a signature that corresponds to that of the "new" being

    used
    > will be called. However, during a "normal" deallocation, there is no

    way to
    > know which version of "new" was previously used, so the usual

    deallocation
    > routine is used (I hope I'm using the term "usual" properly here).

    This is
    > demonstrated in the output shown above.
    >
    > When the statement "delete ptr;" is reached, is there a way to cause

    it to
    > use "operator delete(void*, int)" as the underlying deallocation

    routine
    > rather than "operator delete(void *)"? After all, the usual

    dellaocation
    > routine may not do what's right given that the memory was not

    allocated with
    > the usual allocation routine! (Again, I hope I'm using the term

    "usual"
    > properly.)
    >



    No, there is no way that I am aware of that can make the operator delete
    that you want to be called to get called. This operator delete exists
    primarily because of potential failure of the object construction while
    calling operator new, as you have already mentioned, but if you want to
    call the operator new that takes extra parameters, then while deleting
    that object you have to manually do the destroy-deallocate dance. The
    reason for this is that you may pass pointers to functions that might
    delete this passed pointer, so how can the functions know which operator
    delete to call. So, you have to manually deallocate and delete the
    memory.



    > I am aware that I could do the following in place of "delete ptr;":
    >
    > ptr->~base();
    > base::eek:perator delete(ptr, 243);


    Yes.


    Regards,
    -Dhruv.







    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
     
    Dhruv, Oct 22, 2003
    #3
  4. Dave

    Roger Orr Guest

    "Dave" <> wrote in message
    news:...
    >
    > Hello all,
    >
    > In the code below, I see the following output:
    >
    > base::eek:perator new(size_t, int)
    > base::base()
    > base::~base()
    > base::eek:perator delete(void *)
    >
    > In the case of an exception being thrown during construction, a form of
    > delete with a signature that corresponds to that of the "new" being used
    > will be called. However, during a "normal" deallocation, there is no way

    to
    > know which version of "new" was previously used, so the usual deallocation
    > routine is used (I hope I'm using the term "usual" properly here). This

    is
    > demonstrated in the output shown above.
    >
    > When the statement "delete ptr;" is reached, is there a way to cause it to
    > use "operator delete(void*, int)" as the underlying deallocation routine
    > rather than "operator delete(void *)"? After all, the usual dellaocation
    > routine may not do what's right given that the memory was not allocated

    with
    > the usual allocation routine! (Again, I hope I'm using the term "usual"
    > properly.)


    What actual problem are you trying to solve?
    Do you need code which transparently handles and destroys heap allocated
    objects of both types, or can you separate these two parts of the logic?
    Perhaps you can solve the problem with a pair of classes, or by templatizing
    on allocation strategy - which may be less likely to be error prone.
    Another solution, for example, is to create a pointer-like class which is
    responsible for deleting the non-standard object.
    If you embed allocation information in your class what does this design say
    about objects of this class?

    Roger Orr
    --
    MVP in C++ at www.brainbench.com



    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
     
    Roger Orr, Oct 22, 2003
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. HeroOfSpielburg
    Replies:
    1
    Views:
    397
    Alf P. Steinbach
    Aug 6, 2003
  2. Dodo
    Replies:
    1
    Views:
    366
    Ron Natalie
    Aug 26, 2003
  3. Dave
    Replies:
    2
    Views:
    338
    tom_usenet
    Oct 20, 2003
  4. Peter Olcott
    Replies:
    11
    Views:
    2,775
    David Rubin
    Mar 1, 2004
  5. Jef Driesen
    Replies:
    1
    Views:
    509
    Gernot Frisch
    Jan 19, 2005
Loading...

Share This Page