473,378 Members | 1,468 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

auto_ptr who is right?

struct A
{
void Print() const {
cout << "Print" << endl;
}
};
auto_ptr<AGet()
{
new A; // (1)
// auto_ptr<A>(new A); // (2) works fine
}

int main()
{
auto_ptr<Ap = Get();
p->Print();
}

if use MSVC8.0 it crash, turns out what p contains is a null pointer
if use STLPort, it works fine,

So is there something wrong with the code, or with MSVC8.0
implementation of auto_ptr ?
--
Thanks
Barry
Sep 2 '07 #1
18 2425
On 2 Sep., 15:19, Barry <dhb2...@gmail.comwrote:
struct A
{
void Print() const {
cout << "Print" << endl;
}

};

auto_ptr<AGet()
{
new A; // (1)
// auto_ptr<A>(new A); // (2) works fine
Don't you respect your compilers warnings? This should not compile
without a warning, and you do not return anything - whats returned is
rubbish.
}

int main()
{
auto_ptr<Ap = Get();
p->Print();
Here you dereference garbage. Garbage in means garbase out.

/Peter

[snip]

Sep 2 '07 #2
peter koch wrote:
On 2 Sep., 15:19, Barry <dhb2...@gmail.comwrote:
>struct A
{
void Print() const {
cout << "Print" << endl;
}

};

auto_ptr<AGet()
{
new A; // (1)
// auto_ptr<A>(new A); // (2) works fine

Don't you respect your compilers warnings? This should not compile
without a warning, and you do not return anything - whats returned is
rubbish.
sorry, I didn't compile this code, I just make a mimic example
after I post this thread, I compile this code (add return), and found it
work also on MSVC8
>}

int main()
{
auto_ptr<Ap = Get();
p->Print();
Here you dereference garbage. Garbage in means garbase out.

/Peter

[snip]
Well, this one really crashes!

#include <memory>
#include <iostream>
#include <string>

using namespace std;

struct Pizza
{
Pizza(string const& name) : name_(name) {}
void Show() const
{
cout << name_ << " Pizza" << endl;
}
private:
string name_;
};

struct Pie
{
Pie(string const& name) : name_(name) {}
void Show() const
{
cout << name_ << " Pie" << endl;
}
private:
string name_;
};

class AbstractFactory
{
public:
virtual auto_ptr<PizzaCreatePizza() = 0;

virtual ~AbstractFactory() {}
};

class NestFactory
: public AbstractFactory
{
virtual auto_ptr<PizzaCreatePizza()
{
return new Pizza("Nest");
}
};

int main()
{
auto_ptr<AbstractFactorypFactory(new NestFactory);
auto_ptr<PizzapPizza = pFactory->CreatePizza();
pPizza->Show();
}

--
Thanks
Barry
Sep 2 '07 #3

Barry <dh*****@gmail.comwrote in message...
>
sorry, I didn't compile this code, I just make a mimic example
after I post this thread, I compile this code (add return), and found it
work also on MSVC8
Well, this one really crashes!

#include <memory>
#include <iostream>
#include <string>
using namespace std;

struct Pizza{
Pizza(string const& name) : name_(name) {}
void Show() const {
cout << name_ << " Pizza" << endl;
}
private:
string name_;
};
<snip unused 'Pie' >
class AbstractFactory{ public:
virtual auto_ptr<PizzaCreatePizza() = 0;
virtual ~AbstractFactory() {}
};

class NestFactory : public AbstractFactory {
virtual auto_ptr<PizzaCreatePizza(){
// return new Pizza( "Nest" );
// error: conversion from `Pizza*' to non-scalar type
// `std::auto_ptr<Pizza>' requested

return std::auto_ptr<Pizza>( new Pizza( "Nest" ) );
}
};

int main(){
auto_ptr<AbstractFactorypFactory(new NestFactory);
auto_ptr<PizzapPizza = pFactory->CreatePizza();
pPizza->Show();
}
--
Bob R
POVrookie
Sep 3 '07 #4
BobR wrote:
Barry <dh*****@gmail.comwrote in message...
>sorry, I didn't compile this code, I just make a mimic example
after I post this thread, I compile this code (add return), and found it
work also on MSVC8
Well, this one really crashes!

#include <memory>
#include <iostream>
#include <string>
using namespace std;

struct Pizza{
Pizza(string const& name) : name_(name) {}
void Show() const {
cout << name_ << " Pizza" << endl;
}
private:
string name_;
};
<snip unused 'Pie' >
>class AbstractFactory{ public:
virtual auto_ptr<PizzaCreatePizza() = 0;
virtual ~AbstractFactory() {}
};

class NestFactory : public AbstractFactory {
virtual auto_ptr<PizzaCreatePizza(){

// return new Pizza( "Nest" );
// error: conversion from `Pizza*' to non-scalar type
// `std::auto_ptr<Pizza>' requested

return std::auto_ptr<Pizza>( new Pizza( "Nest" ) );
Thanks for your reply, can you tell me where in the standard talk about
this?

And more, why the example in the OP works with MSVC8 while this one does
NOT?
And why all cases works well with STLPort? Is this a bug in STLPort's
auto_ptr?
>
> }
};

int main(){
auto_ptr<AbstractFactorypFactory(new NestFactory);
auto_ptr<PizzapPizza = pFactory->CreatePizza();
pPizza->Show();
}

--
Thanks
Barry
Sep 3 '07 #5

Barry <dh***@126.comwrote in message...
BobR wrote:

return std::auto_ptr<Pizza>( new Pizza( "Nest" ) );

Thanks for your reply, can you tell me where in the standard talk about
this?

And more, why the example in the OP works with MSVC8 while this one does
NOT?
It does NOT work. Did you read what Peter said?

You can't return an object A pointer where it is expected to return an
std::auto_ptr object. If it does compile and run, it's UB.
What you were trying to do is akin to:
std::string Line("Hello World!");
int Number = Line;
And why all cases works well with STLPort? Is this a bug in STLPort's
auto_ptr?
You'll have to ask that where you got STLPort.

Does this compile for you?

// includes here
struct Pizza{
Pizza( std::string const& name) : name_(name) {}
void Show( std::ostream &out ) const {
out<<name_<<" Pizza"<<std::endl;
}
private:
std::string name_;
};

class AbstractFactory{ public:
virtual std::auto_ptr<PizzaCreatePizza() = 0;
virtual Pizza* CreatePizza2() = 0;
virtual ~AbstractFactory() {}
};

class NestFactory : public AbstractFactory{
virtual std::auto_ptr<PizzaCreatePizza(){
return std::auto_ptr<Pizza>( new Pizza( "Nest" ) );
}
virtual Pizza* CreatePizza2(){
return new Pizza( "Nest2" );
}
};

int main(){
std::auto_ptr<AbstractFactorypFactory( new NestFactory );
std::auto_ptr<PizzapPizza = pFactory->CreatePizza();
pPizza->Show( std::cout );
std::auto_ptr<PizzapPizza2( pFactory->CreatePizza2() );
pPizza2->Show( std::cout );
return 0;
} // main()

--
Bob R
POVrookie
Sep 3 '07 #6
BobR wrote:
Barry <dh***@126.comwrote in message...
>BobR wrote:
>> return std::auto_ptr<Pizza>( new Pizza( "Nest" ) );
Thanks for your reply, can you tell me where in the standard talk about
this?

And more, why the example in the OP works with MSVC8 while this one does
NOT?

It does NOT work. Did you read what Peter said?

You can't return an object A pointer where it is expected to return an
std::auto_ptr object. If it does compile and run, it's UB.
What you were trying to do is akin to:
std::string Line("Hello World!");
int Number = Line;
>And why all cases works well with STLPort? Is this a bug in STLPort's
auto_ptr?

You'll have to ask that where you got STLPort.

Does this compile for you?

// includes here
struct Pizza{
Pizza( std::string const& name) : name_(name) {}
void Show( std::ostream &out ) const {
out<<name_<<" Pizza"<<std::endl;
}
private:
std::string name_;
};

class AbstractFactory{ public:
virtual std::auto_ptr<PizzaCreatePizza() = 0;
virtual Pizza* CreatePizza2() = 0;
virtual ~AbstractFactory() {}
};

class NestFactory : public AbstractFactory{
virtual std::auto_ptr<PizzaCreatePizza(){
return std::auto_ptr<Pizza>( new Pizza( "Nest" ) );
}
virtual Pizza* CreatePizza2(){
return new Pizza( "Nest2" );
}
};

int main(){
std::auto_ptr<AbstractFactorypFactory( new NestFactory );
std::auto_ptr<PizzapPizza = pFactory->CreatePizza();
pPizza->Show( std::cout );
std::auto_ptr<PizzapPizza2( pFactory->CreatePizza2() );
pPizza2->Show( std::cout );
return 0;
} // main()
I think it's not that simple as

string Line("dsdsd");
int i = Line;
with auto_ptr

See from the code of auto_ptr from Dinkumware,
it has a explicit constructor
so the return statement find auto_ptr_ref(void*) to construct auto_ptr
then take this auto_ptr_ref to construct auto_ptr.
that's why the code compiles.

but I didn't see anything about the conversion between auto_ptr_ref and
auto_ptr, it seems to be implementation defined.

So what I want to find out is

template <class T>
auto_ptr<TGetT()
{
return new T;
}

is legal or not? or it's just implementation defined which depends on
the implementation of auto_ptr_ref

--
Thanks
Barry
Sep 3 '07 #7
On Sep 3, 12:23 am, Barry <dh...@126.comwrote:
So what I want to find out is

template <class T>
auto_ptr<TGetT()
{
return new T;

}

is legal or not? or it's just implementation defined which depends on
the implementation of auto_ptr_ref
There is no implicit conversion from a T* to an auto_ptr<T>, because
the auto_ptr constructor that would perform the implicit conversion is
declared "explicit". Therefore, a function returning an auto_ptr must
construct its return value explicitly - as the CreatePizza() routine
that BobR posted, demonstrated:

template <class T>
auto_ptr<TGetT()
{
return auto_ptr<T>(new T);
}

Greg
Sep 3 '07 #8
Greg Herlihy wrote:
On Sep 3, 12:23 am, Barry <dh...@126.comwrote:
>So what I want to find out is

template <class T>
auto_ptr<TGetT()
{
return new T;

}

is legal or not? or it's just implementation defined which depends on
the implementation of auto_ptr_ref

There is no implicit conversion from a T* to an auto_ptr<T>, because
the auto_ptr constructor that would perform the implicit conversion is
declared "explicit". Therefore, a function returning an auto_ptr must
construct its return value explicitly - as the CreatePizza() routine
that BobR posted, demonstrated:

template <class T>
auto_ptr<TGetT()
{
return auto_ptr<T>(new T);
}
Well, when I step into the code with MSVC8, the construction path is
T* -auto_ptr_ref -auto_ptr
which is done implicitly by the compiler, which is not user-expected.
And because auto_ptr_ref is made to hold ref of auto_ptr, not the
pointer itself, so the construction path is ill formed though it
compiles this way.

--
Thanks
Barry
Sep 3 '07 #9
Greg Herlihy wrote:
On Sep 3, 12:23 am, Barry <dh...@126.comwrote:
>So what I want to find out is

template <class T>
auto_ptr<TGetT()
{
return new T;

}

is legal or not? or it's just implementation defined which depends on
the implementation of auto_ptr_ref

There is no implicit conversion from a T* to an auto_ptr<T>, because
the auto_ptr constructor that would perform the implicit conversion is
declared "explicit". Therefore, a function returning an auto_ptr must
construct its return value explicitly - as the CreatePizza() routine
that BobR posted, demonstrated:

template <class T>
auto_ptr<TGetT()
{
return auto_ptr<T>(new T);
}

Greg

Sorry, My bad,
The MSVC8 is broken to report the compile error

#include <memory>

struct A;

struct A_cvt
{
A_cvt(int i)
{
}
};

struct A
{
explicit A(int i) {}
A(A_cvt rhs) {}
};

A GetA()
{
return 1;
}

int main()
{
}

It DO compile the code above. So it makes a construction path
T* -auto_ptr_ref -auto_ptr.
which makes me blur about the *explicit* keyword.

--
Thanks
Barry
Sep 3 '07 #10
Hi!

Barry schrieb:
It DO compile the code above. So it makes a construction path
T* -auto_ptr_ref -auto_ptr.
which makes me blur about the *explicit* keyword.
Any construction path must not include more than _ONE_ implicit
conversion by constructor. Thus the path is illegal and MSVC is wrong.

Frank
Sep 3 '07 #11
On Sep 3, 7:09 am, Frank Birbacher <bloodymir.c...@gmx.netwrote:
Hi!

Barry schrieb:
It DO compile the code above. So it makes a construction path
T* -auto_ptr_ref -auto_ptr.
which makes me blur about the *explicit* keyword.

Any construction path must not include more than _ONE_ implicit
conversion by constructor. Thus the path is illegal and MSVC is wrong.

Frank
I also ran into this issue.
It can be avoided if not using MS compiler extensions.
BUT... you have to give up on your <windowsheader :(

I want a clean solution to this problem, too.

Diego
HP

Sep 3 '07 #12
Hello,
I have to use Visual Studio 2005 at work:-(. Think, MSVC8 is the
associated compiler.
For me auto_ptr of MSVC was broken. Some static cast instead of the
right dynamic one.
Makes polymorphic use impossible. Maybe, this is fixed in your version
of MSVC.
Best regards,
Tobias

Sep 3 '07 #13
Hi!

Tobias schrieb:
I have to use Visual Studio 2005 at work:-(. Think, MSVC8 is the
associated compiler.
For me auto_ptr of MSVC was broken. Some static cast instead of the
right dynamic one.
Makes polymorphic use impossible. Maybe, this is fixed in your version
of MSVC.
MSVC8 is currently the latest (released) compiler. Could you provide a
little program to show the error?

Frank
Sep 3 '07 #14
Tobias wrote:
Hello,
I have to use Visual Studio 2005 at work:-(. Think, MSVC8 is the
associated compiler.
For me auto_ptr of MSVC was broken. Some static cast instead of the
right dynamic one.
Makes polymorphic use impossible. Maybe, this is fixed in your version
of MSVC.
Best regards,
Tobias
Well,
as I test the code on the Dinkumware Exam
http://www.dinkumware.com/exam/default.aspx
All the VC series produce the right compile error against auto_ptr,
except VC6, which is forgivable. so maybe there's already some Service Pack.
Sep 4 '07 #15
// MSVC8 is currently the latest (released) compiler. Could you
provide a
// little program to show the error?
// Try this one with MSVC++ 8.0 and g++ 3.4.4 (or later).
// If both give the same results the error is fixed in your version of
MSVC++.
// If the VC++-Version calls A1::f() this is the error.
// In that case (as I've already mentioned) there is a wrong static
cast in <memory>.

#include<memory>
#include<fstream>

std::ofstream log;

struct A1
{
A1() {
log << "A1::A1()\n";
}

virtual void f() {
log << "A1::f() should never be called.\n";
}

virtual ~A1() {
log << "A1::~A1()\n";
}
};

struct A2
{
A2() {
log << "A2::A2()\n";
}

virtual void g() {
log << "A2::g() should be called the first time.\n";
}

virtual ~A2() {
log << "A2::~A2()\n";
}
};

struct B: public A1, public A2
{
B() {
log << "B::B()\n";
}

virtual void g() {
log << "B::g() should be called the second time.\n";
}

virtual ~B() {
log << "B::~B()\n";
}
};

void f(bool b)
{
std::auto_ptr<A2pA2;

if(b)
pA2 = std::auto_ptr<B>(new B());
else
pA2 = std::auto_ptr<A2>(new A2());

pA2->g();
}

int main()
{
log.open("log");
if(!log) return -1;

f(false);
f(true);

log.close();
return 0;
}
Sep 4 '07 #16
Tobias wrote:
// MSVC8 is currently the latest (released) compiler. Could you
provide a
// little program to show the error?
// Try this one with MSVC++ 8.0 and g++ 3.4.4 (or later).
// If both give the same results the error is fixed in your version of
MSVC++.
// If the VC++-Version calls A1::f() this is the error.
// In that case (as I've already mentioned) there is a wrong static
cast in <memory>.
i didn't find the cast you mentioned.
where?
>
void f(bool b)
{
std::auto_ptr<A2pA2;

if(b)
pA2 = std::auto_ptr<B>(new B());
actually here should've called

template<class Yauto_ptr& operator=(auto_ptr<Y>&) throw(); // 20.4.5.1
construct/copy/destroy:

instead of constructing auto_ptr_ref, then
auto_ptr& operator=(auto_ptr_ref<Xr) throw();

It seems auto_ptr_ref in MSVC8 interferes too much
else
pA2 = std::auto_ptr<A2>(new A2());

pA2->g();
}


--
Thanks
Barry
Sep 5 '07 #17
Barry wrote:
i didn't find the cast you mentioned.
where?
Maybe, I should have said `old-style-cast´ instead of `static cast´
since there is no literal `static_cast´ in <memory>. But the effect is
the same.

Bad things happen in the following snippet of the VC++ version of
<memory>:

8<
template<class _Other>
operator auto_ptr_ref<_Other>() _THROW0()
{ // convert to compatible auto_ptr_ref
_Other *_Testptr = (_Ty *)_Myptr; // test implicit conversion
auto_ptr_ref<_Other_Ans(&_Myptr);
return (_Testptr != 0 ? _Ans : _Ans);
}
>8
8<
template<class _Ty>
struct auto_ptr_ref
{ // proxy reference for auto_ptr copying
auto_ptr_ref(void *_Right)
: _Ref(_Right)
{ // construct from generic pointer to auto_ptr ptr
}

void *_Ref; // generic pointer to auto_ptr ptr
};
>8
Outch! After some test of object-compatibility the object pointer is
reduced to a void* pointer for later usage. This only works if the
vtable is quite simple. If I'm not mistaken the start of the vtable of
the base class must be equal to the start of the vtable of the derived
class. That is not always the case as we have seen in the example.

It looks better in <memoryof g++:
8<
template<typename _Tp1>
operator auto_ptr_ref<_Tp1>() throw()
{ return auto_ptr_ref<_Tp1>(this->release()); }
>8
8<
template<typename _Tp1>
struct auto_ptr_ref
{
_Tp1* _M_ptr;

explicit
auto_ptr_ref(_Tp1* __p): _M_ptr(__p) { }
};
>8
Regards,
Tobias

Sep 5 '07 #18
Tobias wrote:
8<
template<class _Ty>
struct auto_ptr_ref
{ // proxy reference for auto_ptr copying
auto_ptr_ref(void *_Right)
: _Ref(_Right)
{ // construct from generic pointer to auto_ptr ptr
}

void *_Ref; // generic pointer to auto_ptr ptr
};
>8

Outch! After some test of object-compatibility the object pointer is
reduced to a void* pointer for later usage. This only works if the
vtable is quite simple. If I'm not mistaken the start of the vtable of
the base class must be equal to the start of the vtable of the derived
class. That is not always the case as we have seen in the example.
well, it's a mayor bug also inside auto_ptr implementation in MSVC8
the void* is already changed into Ty* in the VC9 beta. It's seems all
the cases here works fine with it.

anyway, it still uses auto_ptr_ref conversion in your case other than
template<class Yauto_ptr& operator=(auto_ptr<Y>&) throw();

it's painful using auto_ptr at least with MSVC, while I felt that I'm
defending it.
It's deprecated in the working draft, said that it will be replaced by
unique_ptr, which borrows the new `Move' syntex. Still a long time to wait.

--
Thanks
Barry
Sep 6 '07 #19

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Marc Schellens | last post by:
I want to use an auto_ptr to a buffer: auto_ptr<char> buffer = new char; But this does not work, as auto_ptr calls delete instead of delete, right? What I can do? Is there a version of...
6
by: Noah Roberts | last post by:
Often I have a method which accepts a pointer to some class as an argument. Usually that pointer is managed by the caller through std::auto_ptr. I would assume that you could pass the auto_ptr in...
4
by: Marcin Vorbrodt | last post by:
A source function is a one that returns an auto_ptr object. A sink function is one that takes auto_ptr as a parameter. So: void Source(auto_ptr<SomeClass> aptr); This will transfer the...
23
by: guru.slt | last post by:
Hi, see this code: auto_ptr<int> int_auto_p(new int(3)); auto_ptr<int> int_auto_p2(int_auto_p.get()); Then, both auto_pointer will own the same object. That will violate the single...
3
by: Evgeny | last post by:
Hi, all! I didn't find yet solution for this problem! Somebody knows where is a catch? Looks like "operator =" or copy constructor not implemented in one of internal templates.... Thanks in...
8
by: Lloyd Dupont | last post by:
I try to use the auto_ptr in my code but that doesn't work. even std::auto_ptr. I guess I have to add an #include statement, but I can't figure out the right file to add. Also I want to use...
23
by: Jeff | last post by:
After reading all I could find about auto_ptr, I decided to write a little program to test my comprehension: #include <iostream> #include <memory> class A { public: void say_hi() {...
14
by: Pep | last post by:
I have a method in a class like this class myClass { ... ctros, dtor, etc ... string myClassMethod() { string myString = "";
39
by: Andre Siqueira | last post by:
Hello all, I have a member function like thist: Query(const std::string & id, std::auto_ptr<Modifiermodif = std::auto_ptr<Modifier>()) when a try to instantiate a Query like ...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.