#include <memory>
struct T {};
std::auto_ptr<T> f() { return new T; }
int main()
{
std::auto_ptr<T> at = f();
std::cout << "test\n";
std::cin.get();
}
The above code should compile and work fine, no? I should not be
getting a crash due to doubly deleted memory segments...right?
Because in MSVC++ 8.0 the above code compiles but crashes. I find it
hard to believe that MSVC could have a library that's so trivially
hosed, but by my understanding of the docs on std::auto_ptr...the above
code should run without crashing.
That doesn't compile in g++. So I changed the source according to what
g++ expects and it works without craishing in both compilers. Dunno why
MSVC lets me return new T, but it does and then can't handle it.
I've used auto_ptr, but never as a return type.
I think you really want to return a T* and store it in auto_ptr.
Otherwise 'at' may be a copy of a temporary auto_ptr.
And that would be bad.
>Because in MSVC++ 8.0 the above code compiles but crashes. I find it
>hard to believe that MSVC could have a library that's so trivially
>hosed, but by my understanding of the docs on std::auto_ptr...the above
>code should run without crashing.
--
Drew Lawson | It's not enough to be alive
| when your future's been deferred
It shouldn't be. The temporary should be assigned to at, which then
holds the ptr while the original temp holds 0.
This is a bug in MSVC++ - I believe you can find it on their website.
/Peter
'std::auto_ptr' has a special copy c-tor, one that takes a non-const
ref. A temporary cannot be used to construct another 'auto_ptr'.
That's the problem, I believe.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
I was basing my original thought on general copying behavior.
Only after being corrected did it sink in that copying the pointer
in an auto_ptr could never make sense, and would always get double
deletes.
Short at least one cup of coffee today.
--
Drew Lawson | What you own is your own kingdom
| What you do is your own glory
| What you love is your own power
| What you live is your own story
> > #include <memory>
> > struct T {};
Looking at the expanded code (your program compiled using -E),
it looks like the VC++ library is missing an explicit on the
constructor of auto_ptr_ref, compared at least to g++. It's
actually hard to say; the standard doesn't say much of anything
about what auto_ptr_ref should look like. The class definition
show it as empty, which IIUC means that it cannot contain any
public members (and the g++ implementation is non-conforming as
well). But without the explicit, you code compiles, since the
pointer returned by new converts implicitly to an auto_ptr_ref,
and auto_ptr has a constructor which takes an auto_ptr_ref. At
any rate, the VC++ auto_ptr_ref is designed to contain a pointer
to the pointer in the auto_ptr which creates it, so it's not
surprising that funny things happen when it is initialized with
something else. (The g++ implementation works differently...
and will leak memory if the auto_ptr_ref isn't used to
initialize an auto_ptr. I don't know what the correct solution
is.)
--
James Kanze (GABI Software) email:james...@gmail.com
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
> >> #include <memory>
> >> struct T {};
> >> std::auto_ptr<T> f() { return new T; }
> >> int main()
> >> {
> >> std::auto_ptr<T> at = f();
> >> std::cout << "test\n";
> >> std::cin.get();
> >> }
> >> The above code should compile and work fine, no? I should
> >> not be getting a crash due to doubly deleted memory
> >> segments...right?
> > I've used auto_ptr, but never as a return type. I think you
> > really want to return a T* and store it in auto_ptr.
> > Otherwise 'at' may be a copy of a temporary auto_ptr.
> > And that would be bad.
> It shouldn't be. The temporary should be assigned to at,
> which then holds the ptr while the original temp holds 0.
That's the way VC++ implements it, and that corresponds
literally to what the standard says to do. Practically,
however... is there a possibility of the auto_ptr_ref outliving
the original auto_ptr used to create it? If so, there could be
a serious problem. G++ avoids this by dropping ownership when
the auto_ptr_ref is created. Which of course, will cause a
memory leak if the auto_ptr_ref isn't ultimately used to craete
an auto_ptr.
One option is for the auto_ptr_ref to hold a reference to the auto_ptr
that created it.
But that's probably too obvious. :-)
Bo Persson
> >>> #include <memory>
> >>> struct T {};
That's basically what VC++ does (IIRC---I don't have access to
VC++ where I am at the moment). Except that in fact, it holds a
pointer to the internals of the auto_ptr, rather than to the
auto_ptr itself. And of course, that gets you into no end of
problems if the auto_ptr_ref has a lifetime beyond that of the
auto_ptr, and is used. I can't see that being a problem in
real code, but I think that the standard does allow something
like:
std::auto_ptr_ref< T > r( functionReturningAutoPtr() ) ;
std::auot_ptr< t > p( r ) ;
In which case, I don't think the VC++ implemenation would
work. IMHO, this particular error is along the same lines as
the fact that std::basic_string<double> core dumps in g++. If
you actually encounter it, you deserve it. (VC++ should either
make the constructor of auto_ptr_ref private, with auto_ptr a
friend, or make it typesafe, rather than just taking a void*,
however.)