auto_ptr memory leak with arrays?

A

Andrew Brampton

Shark said:
Hi, I was reading on http://www.kuro5hin.org/story/2005/10/31/53857/831
that auto_ptr uses "delete" in its destructor instead of delete[]. The
article is fairly recent, so I was wondering if this is true in general
for any hosted implementation.

Yes this is true, I also encountered this problem, so I originally copied
and pasted a auto_ptr implementation and change the one line to delete[].

But now I use boost, which I think a far better idea. Look at boost smart
pointers such as boost::scoped_array.

Andrew
 
A

Axter

Shark said:
Hi, I was reading on http://www.kuro5hin.org/story/2005/10/31/53857/831
that auto_ptr uses "delete" in its destructor instead of delete[]. The
article is fairly recent, so I was wondering if this is true in general
for any hosted implementation.

If you need an array, then you should not be using auto_ptr, and
instead use std::vector.

auto_ptr represents a single object, and std::vector represents
multiple objects.
 
H

Howard Hinnant

"Axter said:
Shark said:
Hi, I was reading on http://www.kuro5hin.org/story/2005/10/31/53857/831
that auto_ptr uses "delete" in its destructor instead of delete[]. The
article is fairly recent, so I was wondering if this is true in general
for any hosted implementation.

If you need an array, then you should not be using auto_ptr, and
instead use std::vector.

auto_ptr represents a single object, and std::vector represents
multiple objects.

The one thing that auto_ptr does that vector doesn't (and I don't know
whether it is important in this case) is allow the transfer of pointer
ownership from one object to another. I'm not saying auto_ptr should be
used. I'm just saying that there is a real need for:

smart_pointer<T[]> p(new T [size]);

-Howard
 
A

Axter

Howard said:
Axter said:
Shark said:
Hi, I was reading on http://www.kuro5hin.org/story/2005/10/31/53857/831
that auto_ptr uses "delete" in its destructor instead of delete[]. The
article is fairly recent, so I was wondering if this is true in general
for any hosted implementation.

If you need an array, then you should not be using auto_ptr, and
instead use std::vector.

auto_ptr represents a single object, and std::vector represents
multiple objects.

The one thing that auto_ptr does that vector doesn't (and I don't know
whether it is important in this case) is allow the transfer of pointer
ownership from one object to another. I'm not saying auto_ptr should be
used. I'm just saying that there is a real need for:

smart_pointer<T[]> p(new T [size]);

Good point. I didn't consider that.
 
J

Jeff Flinn

Howard said:
Axter said:
Shark said:
Hi, I was reading on
http://www.kuro5hin.org/story/2005/10/31/53857/831 that auto_ptr
uses "delete" in its destructor instead of delete[]. The article is
fairly recent, so I was wondering if this is true in general for
any hosted implementation.

If you need an array, then you should not be using auto_ptr, and
instead use std::vector.

auto_ptr represents a single object, and std::vector represents
multiple objects.

The one thing that auto_ptr does that vector doesn't (and I don't know
whether it is important in this case) is allow the transfer of pointer
ownership from one object to another.

Wouldn't std::swap( v1, v2 ) suffice.

Jeff
 
D

Daniel T.

Howard Hinnant said:
Axter said:
Shark said:
Hi, I was reading on http://www.kuro5hin.org/story/2005/10/31/53857/831
that auto_ptr uses "delete" in its destructor instead of delete[]. The
article is fairly recent, so I was wondering if this is true in general
for any hosted implementation.

If you need an array, then you should not be using auto_ptr, and
instead use std::vector.

auto_ptr represents a single object, and std::vector represents
multiple objects.

The one thing that auto_ptr does that vector doesn't (and I don't know
whether it is important in this case) is allow the transfer of pointer
ownership from one object to another. I'm not saying auto_ptr should be
used. I'm just saying that there is a real need for:

smart_pointer<T[]> p(new T [size]);

There is no need for such a construct.


The reason auto_ptr exists is to ensure that the memory will be freed in
the presents of multiple exist points in a function (due to exceptions.)
This problem doesn't exist with vectors.
 
H

Howard Hinnant

The one thing that auto_ptr does that vector doesn't (and I don't know
whether it is important in this case) is allow the transfer of pointer
ownership from one object to another. I'm not saying auto_ptr should be
used. I'm just saying that there is a real need for:

smart_pointer<T[]> p(new T [size]);

There is no need for such a construct.


The reason auto_ptr exists is to ensure that the memory will be freed in
the presents of multiple exist points in a function (due to exceptions.)
This problem doesn't exist with vectors.[/QUOTE]

That's one reason auto_ptr exists. Another is to transfer ownership of
the pointer, hence the member: release(). Indeed, it is often when a
combination of these two needs exist that auto_ptr shines:

void
A<T>::foo(T* p) {
auto_ptr<T> ap(p); // aggressively grab ownership
// do something here that might throw
// ...
a_member_ = ap.release(); // now A<T> owns the pointer
}

Whether or not A<T>::foo succeeds, it will grab ownership of the passed
pointer, insuring that it won't get leaked.

Just because p is a pointer to an array of T instead of to a single T is
no reason to claim this use case does not exist.

-Howard
 
H

Howard Hinnant

The one thing that auto_ptr does that vector doesn't (and I don't know
whether it is important in this case) is allow the transfer of pointer
ownership from one object to another.

Wouldn't std::swap( v1, v2 ) suffice.[/QUOTE]

<nod> I should have clarified: Allow the transfer of pointer ownership
among disparate types (via auto_ptr<T>::release).

-Howard
 
D

Daniel T.

Howard Hinnant said:
The one thing that auto_ptr does that vector doesn't (and I don't know
whether it is important in this case) is allow the transfer of pointer
ownership from one object to another. I'm not saying auto_ptr should be
used. I'm just saying that there is a real need for:

smart_pointer<T[]> p(new T [size]);

There is no need for such a construct.


The reason auto_ptr exists is to ensure that the memory will be freed in
the presents of multiple exist points in a function (due to exceptions.)
This problem doesn't exist with vectors.

That's one reason auto_ptr exists. Another is to transfer ownership of
the pointer, hence the member: release(). [/QUOTE]

You don't need an auto_ptr to transfer ownership, that is not one of the
reasons for its existence. auto_ptr's *sole* reason for existence is to
ensure that the delete isn't missed.
void
A<T>::foo(T* p) {
auto_ptr<T> ap(p); // aggressively grab ownership
// do something here that might throw
// ...
a_member_ = ap.release(); // now A<T> owns the pointer
}

Whether or not A<T>::foo succeeds, it will grab ownership of the passed
pointer, insuring that it won't get leaked.

With a vector, the memory won't get leaked...
 
H

Howard Hinnant

"Daniel T. said:
You don't need an auto_ptr to transfer ownership, that is not one of the
reasons for its existence. auto_ptr's *sole* reason for existence is to
ensure that the delete isn't missed.

Then perhaps you can petition the standards committee to remove
auto_ptr's release() member function. You may submit your request
directly to me if you like. Or you can post it to comp.std.c++, and
I'll pick it up from there and create a formal defect report.
With a vector, the memory won't get leaked...

Please tell me how A<T>::foo(T* p) is going to assure ownership
possession of p while at the same time needing to acquire other
resources in order to do so. I'll be especially interested in how
vector plays a role if p is a pointer which was new'd with new[]. If
you're looking for a motivating example, consider a shared_ptr_array
constructor taking a T*.

Perhaps you'll come up with something using try/catch instead of a local
object? That's certainly a respectable approach, but not what I would
personally recommend (assuming the existence of an efficient smart
pointer that will delete with delete[]). It might look like:

void
A<T>::foo(T* p)
{
try
{
// do something here that might throw
// ...
a_member_ = p; // now A<T> owns the pointer
}
catch (...)
{
delete [] p;
throw;
}
}

Personally I'd take this alternative any day:

void
A<T>::foo(T* p)
{
smart_ptr<T[]> sp(p);
// do something here that might throw
// ...
a_member_ = sp.release(); // now A<T> owns the pointer
}

-Howard
 
D

Daniel T.

Howard Hinnant said:
Then perhaps you can petition the standards committee to remove
auto_ptr's release() member function. You may submit your request
directly to me if you like. Or you can post it to comp.std.c++, and
I'll pick it up from there and create a formal defect report.

No need.
With a vector, the memory won't get leaked...

Please tell me how A<T>::foo(T* p) is going to assure ownership
possession of p while at the same time needing to acquire other
resources in order to do so. I'll be especially interested in how
vector plays a role if p is a pointer which was new'd with new[]. If
you're looking for a motivating example, consider a shared_ptr_array
constructor taking a T*.

A rather contrived problem. The easiest way would be to pass p by value.

Perhaps you'll come up with something using try/catch instead of a local
object? That's certainly a respectable approach, but not what I would
personally recommend (assuming the existence of an efficient smart
pointer that will delete with delete[]). It might look like:

void
A<T>::foo(T* p)
{
try
{
// do something here that might throw
// ...
a_member_ = p; // now A<T> owns the pointer
}
catch (...)
{
delete [] p;
throw;
}
}

Personally I'd take this alternative any day:

void
A<T>::foo(T* p)
{
smart_ptr<T[]> sp(p);
// do something here that might throw
// ...
a_member_ = sp.release(); // now A<T> owns the pointer
}

That's fine by me, do it however you want.
 
D

Daniel T.

Howard Hinnant said:
Wouldn't std::swap( v1, v2 ) suffice.

<nod> I should have clarified: Allow the transfer of pointer ownership
among disparate types (via auto_ptr<T>::release).[/QUOTE]

Again, if the pointer to array construct isn't used, then there is no
need for an auto_ptr that has delete[]. Just use the standard containers.
 

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,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top