Just want to make sure...

N

Noah Roberts

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

Noah Roberts

Noah said:
#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.
 
D

Drew Lawson

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

Noah Roberts

Drew said:
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.
 
P

peter koch

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

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

/Peter
 
V

Victor Bazarov

Noah said:
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.

V
 
D

Drew Lawson

'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.
 
J

James Kanze

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.

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

James Kanze

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

Bo Persson

James said:
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.)

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
 
J

James Kanze

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

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

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

No members online now.

Forum statistics

Threads
473,733
Messages
2,569,440
Members
44,831
Latest member
HealthSmartketoReviews

Latest Threads

Top