Re: deleting dynamically allocated objects in a container
Leigh Johnston wrote:
"James Kanze" <james.kanze@gmail.com> wrote in message
news:2f94d8fb-58fd-4f29-8e65-08d2d5ee8d82@l20g2000yqm.googlegroups.com...
On Aug 9, 3:51 pm, "subramanian10...@yahoo.com, India"
<subramanian10...@yahoo.com> wrote:
Suppose 'Test' is a class. I dynamically allocate few 'Test'
objects and push them into a vector<Test*>. I want to delete
the dynamically allocated 'Test' objects using a Standard
Library Algorithm instead of writing a hand-written 'for
loop'.
Following is my attempt: (I am using cout statements in the
ctor and dtor only for understanding purpose).
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Test
{
public:
explicit Test(int arg = 0);
~Test();
private:
int val;
};
inline Test::Test(int arg) : val(arg)
{
cout << "From Test ctor: " << val << endl;
}
inline Test::~Test()
{
cout << "From Test dtor: " << val << endl;
}
inline void delete_pointer(Test* & arg)
{
delete arg;
arg = 0;
Purely formally, the above results in undefined behavior. (In
practice, I wouldn't worry about it.)
I am have problems spotting the UB, care to elaborate further?
That's about the container containing invalid pointer values. That renders
them non-copyconstructible and non-assignable (since the required lvalue to
rvalue conversion is UB). Therefore, the container contains objects that do
not satisfy the conceptual requirements of the container.
That said, I think, even
int main ( void ) {
std::vector< int* > v ( 10 );
int * the_mighty_invalidator = new int ( 3 );
delete the_mighty_invalidator;
... UB from here on ...
}
has UB under a possible (although clearly not intended) interpretation of
the standard: conceptual requirements are phrased "per type". In the above
example, int* becomes non-assignable and non-copyconstructible. Thus, even
though the vector does not contain any of the bad values, the conceptual
requirements are not satisfied.
Just goes to show that requirements are very, _very_ hard to phrase. It also
goes to show that the standard has to be interpreted with a good measure of
common sense. Now, the first interpretation could actually be intended. It
is clear that a vector implementation will ruthlessly copy and move objects
around. If they happen to be invalid pointers, you would want the vector
operations UB if the underlying pointer assignments are UB.
Now, as for the question whether an lvalue to rvalue conversion of an
invalid pointer _should_ be UB, I have no opinion to offer. Also, the
interpretation seems a little strict. But the intend of [4.1/1] seems to be
that lvalue to rvalue conversions on invalid values are UB, e.g., the bit
about uninitialized values.
Best
Kai-Uwe Bux