object lifetime

R

REH

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;
}
 
V

Victor Bazarov

REH said:
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
 
J

James Kanze

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.
 
J

Junhui Tong

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




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. :)
 
R

Robert Bauck Hamar

Junhui said:
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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,961
Messages
2,570,131
Members
46,689
Latest member
liammiller

Latest Threads

Top