object lifetime

Discussion in 'C++' started by REH, Jul 19, 2007.

  1. REH

    REH Guest

    I've been trying to better understand the subtle rules for object
    lifetime. The standard says that pointers to the memory of a
    dynamically allocated object may be used in limited ways after the
    object's destructor has executed (but the memory not deallocated).
    Specifically, the pointer must be a void*. Does that mean, the
    following is well defined?

    #include <new>

    class T {};

    int main()
    {
    T* p = new T();

    p->~T();

    operator delete(static_cast<void*>(p));

    return 0;
    }
    REH, Jul 19, 2007
    #1
    1. Advertising

  2. REH wrote:
    > I've been trying to better understand the subtle rules for object
    > lifetime. The standard says that pointers to the memory of a
    > dynamically allocated object may be used in limited ways after the
    > object's destructor has executed (but the memory not deallocated).
    > Specifically, the pointer must be a void*. Does that mean, the
    > following is well defined?
    >
    > #include <new>
    >
    > class T {};
    >
    > int main()
    > {
    > T* p = new T();
    >
    > p->~T();
    >
    > operator delete(static_cast<void*>(p));
    >
    > return 0;
    > }


    I think it's OK to do that. The other use is construction of another
    object in the memory, using placement new syntax:

    T* p = new T();
    p->~T();
    new (p) T(); // another object constructed
    delete p;

    As I understand it, std::vector does it all the time.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Jul 19, 2007
    #2
    1. Advertising

  3. REH

    James Kanze Guest

    On Jul 19, 6:02 pm, REH <> wrote:
    > I've been trying to better understand the subtle rules for object
    > lifetime. The standard says that pointers to the memory of a
    > dynamically allocated object may be used in limited ways after the
    > object's destructor has executed (but the memory not deallocated).
    > Specifically, the pointer must be a void*.


    There's no strict requirement that it be converted to void*. As
    long as the memory has not been freed, you can copy and compare
    the pointer all you want; you can only dereference if you
    convert it to a pointer to character type, and access the
    underlying bytes as char or unsigned char.

    > Does that mean, the following is well defined?


    As written, yes, but only because T is the most derived class.

    > #include <new>


    > class T {};


    > int main()
    > {
    > T* p = new T();
    > p->~T();
    > operator delete(static_cast<void*>(p));


    You don't need the static_cast here; in fact, it doesn't change
    anything.

    This is legal as long as p pointed to the most derived object
    initially. If you'd written something like:

    Base* p = new Derived ;
    // ...
    p->~Base() ;
    operator delete( p ) ;

    Then the behavior would be undefined.

    > return 0;
    > }


    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jul 20, 2007
    #3
  4. REH

    Junhui Tong Guest

    James Kanze wrote:
    > As written, yes, but only because T is the most derived class.
    >
    >> #include <new>

    >
    >> class T {};

    >
    >> int main()
    >> {
    >> T* p = new T();
    >> p->~T();
    >> operator delete(static_cast<void*>(p));

    >
    > You don't need the static_cast here; in fact, it doesn't change
    > anything.

    Can you explain why `operator delete' doesn't call T::~T() even if its
    parameter is `T *'?

    Thank you. :)
    Junhui Tong, Jul 24, 2007
    #4
  5. Junhui Tong wrote:

    > James Kanze wrote:
    >> As written, yes, but only because T is the most derived class.
    >>
    >>> #include <new>

    >>
    >>> class T {};

    >>
    >>> int main()
    >>> {
    >>> T* p = new T();
    >>> p->~T();
    >>> operator delete(static_cast<void*>(p));

    >>
    >> You don't need the static_cast here; in fact, it doesn't change
    >> anything.

    > Can you explain why `operator delete' doesn't call T::~T() even if its
    > parameter is `T *'?


    1) Because calling destructors is not the job of operator delete()
    2) Operator delete's parameter is a void*. Even if you call it with another
    pointer as argument, it will be converted to a void* upon calling.
    3) Operator delete is not the delete operator.

    --
    rbh
    Robert Bauck Hamar, Jul 24, 2007
    #5
    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. Colin Basterfield

    lifetime of Session object

    Colin Basterfield, Jun 2, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    439
    Colin Basterfield
    Jun 3, 2004
  2. Replies:
    0
    Views:
    420
  3. =?Utf-8?B?RGlmZmlkZW50?=

    Worker process and Cache object's lifetime

    =?Utf-8?B?RGlmZmlkZW50?=, Feb 2, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    470
    =?Utf-8?B?UGV0ZXIgQnJvbWJlcmcgW0MjIE1WUF0=?=
    Feb 2, 2006
  4. pt
    Replies:
    8
    Views:
    774
  5. Oliver Tengler

    SWIG: Tie lifetime of object to a result

    Oliver Tengler, Nov 14, 2003, in forum: Python
    Replies:
    0
    Views:
    275
    Oliver Tengler
    Nov 14, 2003
Loading...

Share This Page