delete in-place corresponding to placement new?

P

Peter Olcott

I have just built a class that provides the most useful subset of std::vector
functionality for use by compilers that lack template capability.

http://home.att.net/~olcott/std_vect.html

Through suggestions from this news group I was able to exactly duplicate
the interface of std::vector, except for one aspect. What I need is a way
to invoke the destructor on elements of an array without de-allocating the
memory of this array. This would correspond to placement new, constructing
without allocating. The most obvious way that comes to mind is to merely
explicitly invoke the destructor. This capability is not available on a circa
1990 compiler. Does anyone have any good ideas?
 
J

Jonathan Turkanis

Peter Olcott said:
I have just built a class that provides the most useful subset of std::vector
functionality for use by compilers that lack template capability.

http://home.att.net/~olcott/std_vect.html

Through suggestions from this news group I was able to exactly duplicate
the interface of std::vector, except for one aspect.

So you got placement new to work? Congratulations!
What I need is a way
to invoke the destructor on elements of an array without de-allocating the
memory of this array. This would correspond to placement new, constructing
without allocating. The most obvious way that comes to mind is to merely
explicitly invoke the destructor.

That's the way to do it.
This capability is not available on a circa
1990 compiler. Does anyone have any good ideas?

If you don't mind being intrusive, you can require that each
user-defined type provide a destroy function. Otherwise, I don't know.

What syntax are you using for the destructor invocation?

Jonathan
 
R

Rob Williscroft

Peter Olcott wrote in
I have just built a class that provides the most useful subset of
std::vector functionality for use by compilers that lack template
capability.

http://home.att.net/~olcott/std_vect.html

Through suggestions from this news group I was able to exactly
duplicate the interface of std::vector, except for one aspect. What I
need is a way to invoke the destructor on elements of an array without
de-allocating the memory of this array. This would correspond to
placement new, constructing without allocating. The most obvious way
that comes to mind is to merely explicitly invoke the destructor. This
capability is not available on a circa 1990 compiler. Does anyone have
any good ideas?

Assuming that you can't do:

template < typename T >
inline void destroy( T *t )
{
t->~T();
}

Then you could try:

#define OFFSETOFF( Class, Member ) \
(((char *)&((Class *)0)->Member) - ((char *)0))

template < class T >
struct cheat_detor
{
T item;

inline void operator delete (void *) {}

static void destroy( T *ptr )
{
delete (
(cheat_detor< T > *)
(((char *)ptr) - OFFSETOFF( cheat_detor< T >, item ))
);
}
};

template < class T >
inline void destroy( T * ptr )
{
cheat_detor< T >::destroy( ptr );
}

The above is non-standard code, infact g++ will issue a warning
if T is a non-POD type say:

struct X
{
X() {}
~X() {}
};

Rob.
 
P

Peter Olcott

So you got placement new to work? Congratulations!
Many people suggested placement new, tom_usenet not
only showed me how to make it work on modern compilers,
but also provided the required code to make it work on my
antique compiler.
If you don't mind being intrusive, you can require that each
user-defined type provide a destroy function. Otherwise, I don't know.
This is how I got it to work. Before placement new, I also had to have
two Construct functions: Construct() and Construct(const &)
What syntax are you using for the destructor invocation?
The currently required member function is merely:
Destruct(); // This invokes the body of the user defined destructor.
The easiest way to do this is to provide the body of the destructor
within Destruct(), and then have ~UserType() { Destruct(); };
 
P

Peter Olcott

#define OFFSETOFF( Class, Member ) \
(((char *)&((Class *)0)->Member) - ((char *)0))

I think that this seems to be some sort of direct invocation
of the destructor. I can't directly invoke destructors, nor
do I have any template cabability at all. This is for a 1990
C++ compiler that does not have: templates, exceptions,
namespace, direct destructor calls, a delete[]() operator.
 
J

Jonathan Turkanis

The currently required member function is merely:
Destruct(); // This invokes the body of the user defined destructor.
The easiest way to do this is to provide the body of the destructor
within Destruct(), and then have ~UserType() { Destruct(); };

I meant, what syntax are you using to invoke the destructor
explicitly?

Jonathan
 
D

David Rubin

Peter said:
I have just built a class that provides the most useful subset of std::vector
functionality for use by compilers that lack template capability.

http://home.att.net/~olcott/std_vect.html

Through suggestions from this news group I was able to exactly duplicate
the interface of std::vector, except for one aspect. What I need is a way
to invoke the destructor on elements of an array without de-allocating the
memory of this array.

I am confused by the last sentence. AFAICT, std::vector does not invoke
the destructor function on its elements. Although the STL documentation
says, in the case of std::vector::erase for example,
"a.erase(p)...[d]estroys the element pointed to by p and removes it from
a," it is unclear to me that *p's destructor is ever executed.
Certainly, I have not determined this to be the case through simple tests.

/david
 
P

Peter Olcott

Through suggestions from this news group I was able to exactly duplicate
I am confused by the last sentence. AFAICT, std::vector does not invoke
the destructor function on its elements. Although the STL documentation
says, in the case of std::vector::erase for example,

I am not speaking from the point of view of the user of this class.
I am speaking from the point of view of the implementor of this
class. Regradless of what the user documentation says, std::vector
must call the destructor on elements of an array, when it moves
elements from one array to another, upon memory re-allocation.
 
P

Peter Olcott

I meant, what syntax are you using to invoke the destructor
explicitly?

Jonathan
It turns out that the direct destructor call is possible in Borland Turbo C++
1.0, yet it requires non-standard sytax...

Array[N].UserType::~UserType(); // works correctly.
Array[N].~UserType() // is supposed to work, yet doen't
 
J

Jonathan Turkanis

Peter Olcott said:
I meant, what syntax are you using to invoke the destructor
explicitly?

Jonathan
It turns out that the direct destructor call is possible in Borland Turbo C++
1.0, yet it requires non-standard sytax...

Array[N].UserType::~UserType(); // works correctly.
Array[N].~UserType() // is supposed to work, yet
doen't

Good. You're all set now!

Jonathan
 
B

Buster

David said:
Peter said:
I have just built a class that provides the most useful subset of
std::vector
functionality for use by compilers that lack template capability.

http://home.att.net/~olcott/std_vect.html

Through suggestions from this news group I was able to exactly duplicate
the interface of std::vector, except for one aspect. What I need is a way
to invoke the destructor on elements of an array without de-allocating
the
memory of this array.


I am confused by the last sentence. AFAICT, std::vector does not invoke
the destructor function on its elements. Although the STL documentation
says, in the case of std::vector::erase for example,
"a.erase(p)...[d]estroys the element pointed to by p and removes it from
a," it is unclear to me that *p's destructor is ever executed.
Certainly, I have not determined this to be the case through simple tests.

/david

David, your tests are not correct. Try this:

#include <vector>
#include <iostream>

struct X { ~X () { std::cout << "An X is being destroyed.\n"; } };

int main ()
{
{
std::vector <X> v (3);
std::cout << "The vector has been constructed.\n";
a.erase (a.begin ());
std::cout << "One element has just been erased.\n";
}
std::cout << "The vector has been destroyed.\n";
}

It is important that when objects of a class which has a destructor are
destroyed the destructor is called.

Regards,
Buster
 
D

David Rubin

Buster wrote:

[snip]
[...] AFAICT, std::vector does not
invoke the destructor function on its elements. Although the STL
documentation says, in the case of std::vector::erase for example,
"a.erase(p)...[d]estroys the element pointed to by p and removes it
from a," it is unclear to me that *p's destructor is ever executed.
Certainly, I have not determined this to be the case through simple
tests.

/david

David, your tests are not correct. Try this:

#include <vector>
#include <iostream>

struct X { ~X () { std::cout << "An X is being destroyed.\n"; } };

int main ()
{
{
std::vector <X> v (3);
std::cout << "The vector has been constructed.\n";
a.erase (a.begin ());
std::cout << "One element has just been erased.\n";
}
std::cout << "The vector has been destroyed.\n";
}

It is important that when objects of a class which has a destructor are
destroyed the destructor is called.

I was confused about the difference between calling the destructor and
deleting the object. For example, v.erase(v.begin()) does call the
destructor for, e.g., the v[0] object; I did see this in my test.
However, replacing the above with

std::vector<X*> v(1);
v[0] = new X;

the call

v.erase(v.begin());

does not 'delete' v[0].

/david
 

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

Forum statistics

Threads
474,001
Messages
2,570,254
Members
46,849
Latest member
Fira

Latest Threads

Top