Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Just want to make sure...

0 views
Skip to first unread message

Noah Roberts

unread,
Apr 28, 2009, 3:05:56 PM4/28/09
to
#include <iostream>

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

Noah Roberts

unread,
Apr 28, 2009, 3:10:13 PM4/28/09
to
Noah Roberts wrote:
> #include <iostream>
>
> #include <memory>
>
> struct T {};
>
> std::auto_ptr<T> f() { return new T; }

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.

Drew Lawson

unread,
Apr 28, 2009, 3:17:01 PM4/28/09
to
In article <49f75393$0$2709$cc2e...@news.uslec.net>

Noah Roberts <no...@nowhere.com> writes:
>#include <iostream>
>
>#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.

>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

Noah Roberts

unread,
Apr 28, 2009, 3:20:11 PM4/28/09
to
Drew Lawson wrote:
> In article <49f75393$0$2709$cc2e...@news.uslec.net>
> Noah Roberts <no...@nowhere.com> writes:
>> #include <iostream>
>>
>> #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.

peter koch

unread,
Apr 28, 2009, 3:21:06 PM4/28/09
to

This is a bug in MSVC++ - I believe you can find it on their website.

/Peter

Victor Bazarov

unread,
Apr 28, 2009, 3:34:03 PM4/28/09
to

'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

Drew Lawson

unread,
Apr 28, 2009, 3:39:14 PM4/28/09
to
In article <gt7lms$1f0$1...@news.datemas.de>

Victor Bazarov <v.Aba...@comAcast.net> writes:
>Noah Roberts wrote:
>> Drew Lawson wrote:
>>> In article <49f75393$0$2709$cc2e...@news.uslec.net>
>>> Noah Roberts <no...@nowhere.com> writes:
>>>> #include <iostream>
>>>>
>>>> #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.
>
>'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.

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

James Kanze

unread,
Apr 29, 2009, 5:01:16 AM4/29/09
to

> > #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

James Kanze

unread,
Apr 29, 2009, 5:07:46 AM4/29/09
to
On Apr 28, 9:20 pm, Noah Roberts <n...@nowhere.com> wrote:
> Drew Lawson wrote:
> > In article <49f75393$0$2709$cc2e3...@news.uslec.net>

> > Noah Roberts <n...@nowhere.com> writes:
> >> #include <iostream>

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

Bo Persson

unread,
May 1, 2009, 5:23:03 AM5/1/09
to

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


James Kanze

unread,
May 1, 2009, 6:25:26 AM5/1/09
to

> >>> #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.)

0 new messages