473,320 Members | 2,012 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,320 software developers and data experts.

A Sample auto_ptr implementation

Hi All,

I'm building a sample application that uses a custom auto_ptr
implementation.
The program crashes with the following output:-

Output (Debug Assertion failed)
----------
release called
copy constructor
aap: ptr2= 10
aap: ptr3= 20
aap: ptr3= 10
aap: exiting app
Deleting pointee...10
Deleting pointee...-572662307 (...problem ?)

Code
--------

#include<iostream>

using namespace std;

// MyAutoPtr Interface
template <class T>
class MyAutoPtr
{
public:

explicit MyAutoPtr(T* ptr=0);

~MyAutoPtr();

template <class U>
MyAutoPtr(MyAutoPtr<U*rhs);

//copy constructor member template, initialize this member pointer
with any other compatible auto_ptr
template <class U>
MyAutoPtr(MyAutoPtr<U>& rhs);

//assignment operator
template <class U>
MyAutoPtr<T>& operator=(MyAutoPtr<U>& rhs);

//relinquish ownership
T* release();

T* get() const;

//reset the auto_ptr, delete pointee, assume ownership of p
void reset(T* ptr=0);

T& operator*() const;
T* operator->() const;
private:

T* pointee;
//template <class U>
//friend class MyAutoPtr<U>;
};

//Implementation

template<typename T>
inline MyAutoPtr<T>::MyAutoPtr(T* ptr):pointee(ptr)
{ }

template <class T>
inline MyAutoPtr<T>::~MyAutoPtr()
{
if(pointee)
{
cout<<"\n\t Deleting pointee..."<<*pointee;
delete pointee;
}
}

template <class T>
template <class U>
inline MyAutoPtr<T>::MyAutoPtr(MyAutoPtr<U>& rhs) :
pointee(rhs.release())
{
cout<<"\n\t copy constructor";
}

template<class T>
template<class U>
MyAutoPtr<T>& MyAutoPtr<T>::operator=(MyAutoPtr<U>& rhs)
{
cout<<"\n\t Inside operator=";
if(this!=&rhs)
{
cout<<"\n\t Inside operator=, calling reset";
reset(rhs.release());
}
return *this;
}

template <class T>
T* MyAutoPtr<T>::get() const
{
return pointee;
}

template <class T>
inline T& MyAutoPtr<T>::operator *() const
{
return *pointee;
}

template<class T>
inline T* MyAutoPtr<T>::operator->() const
{ return pointee; }

template<class T>
T* MyAutoPtr<T>::release()
{
cout<<"\n\t release called";
T* oldp=pointee;
pointee=0;

return oldp;
}

template<class T>
void MyAutoPtr<T>::reset(T* p)
{
cout<<"\n\t reset called";
if(pointee!=p)
{
delete pointee;
//pointee=0;
}

pointee=p;
}

void main()
{
MyAutoPtr<intintp(new int(10));
MyAutoPtr<intintp2(intp);
MyAutoPtr<intintp3(new int(20));

//cout<<"ptr1= "<<*intp;
cout<<"\n\t aap: ptr2= "<<*intp2;
cout<<"\n\t aap: ptr3= "<<*intp3;

intp3 = intp2; //
============================== 1

cout<<"\n\t aap: ptr3= "<<*intp3;

cout<<"\n\t aap: exiting app";
}

It seems, on debugging, that class's custom operator= is somehow not
been called at 1 and hence a problem while destructing. (since delete
is being called twice on the same pointer)
---------------------------------------------------------------------------------------------------------

Q1. Any problems with the above code ?
Q2. What is causing operator= not to be called and how to fix it ?
Q3. Following statements (in the class interface) cause compiler
errors, if not commented out

private:
T* pointee;
//template <class U>
//friend class MyAutoPtr<U>;

MSDN defines this error as:-

Compiler Error C3772
Error Message
"name" : invalid friend template declaration

It is invalid to declare a friend of a class template specialization.
You cannot declare an explicit or partial specialization of a class
template and in the same statement declare a friend of that
specialization. The name placeholder identifies the invalid
declaration.
To correct this error
-Do not declare a friend of a class template specialization.
-If appropriate for your application, declare a friend of the class
template, or declare a friend of a particular partial or explicit
specialization.

Why such error, if this is not a specialization? or is it a
specialization somehow?
---------------------------------------------------------------------------------------------------------

Any help will be highly appreciated!

Thanks!
Oct 13 '08 #1
17 10036
Try to define assignment operator without template U parameter:

//assignment operator
MyAutoPtr<T>& operator=(MyAutoPtr<T>& rhs);

Why do you need that 'U' anyway, release should return the pointer to
be passed to reset, so T and U should be equal.

Oct 13 '08 #2
Ankur Arora wrote:
Hi All,

I'm building a sample application that uses a custom auto_ptr
implementation.
The program crashes with the following output:-

Output (Debug Assertion failed)
----------
release called
copy constructor
aap: ptr2= 10
aap: ptr3= 20
aap: ptr3= 10
aap: exiting app
Deleting pointee...10
Deleting pointee...-572662307 (...problem ?)

Code
--------
Just a data point: your code works for me with output

release called
copy constructor
aap: ptr2= 10
aap: ptr3= 20
Inside operator=
Inside operator=, calling reset
release called
reset called
aap: ptr3= 10
aap: exiting app
Deleting pointee...10

So I just have nits:

#include<iostream>

using namespace std;
It's a bad idea to use using namespace std in a header.

[snip]
template <class T>
inline MyAutoPtr<T>::~MyAutoPtr()
{
if(pointee)
{
cout<<"\n\t Deleting pointee..."<<*pointee;
delete pointee;
}
}
delete will perform its own check for 0. It is required to be a null-op in
that case.
[snip]
template<class T>
template<class U>
MyAutoPtr<T>& MyAutoPtr<T>::operator=(MyAutoPtr<U>& rhs)
{
cout<<"\n\t Inside operator=";
if(this!=&rhs)
This if-clause will not compile when T and U are different.

You could use

if ( this->pointee == rhs.pointee )

instead (I think).
{
cout<<"\n\t Inside operator=, calling reset";
reset(rhs.release());
}
return *this;
}
[snip]
void main()
[snip]

Main returns int. I get an error with g++ at this point.

It seems, on debugging, that class's custom operator= is somehow not
been called at 1 and hence a problem while destructing. (since delete
is being called twice on the same pointer)
---------------------------------------------------------------------------------------------------------

Q1. Any problems with the above code ?
It works with g++.
Q2. What is causing operator= not to be called and how to fix it ?
A bug in your compiler?
[snip]
Best

Kai-Uwe Bux
Oct 13 '08 #3
Yakov Gerlovin wrote:
Try to define assignment operator without template U parameter:

//assignment operator
MyAutoPtr<T>& operator=(MyAutoPtr<T>& rhs);

Why do you need that 'U' anyway, release should return the pointer to
be passed to reset, so T and U should be equal.
He needs it to support polymorphism. When D is derived from B, MyAutoPtr<B>
should be constructible and assignable from MyAutoPtr<D>.

But the OP could define copy-constructor and assignment operator from T
separately. For the copy-constructor, I recall that this is needed. I am
not sure if it is needed for the assignment operator.
Best

Kai-Uwe Bux
Oct 13 '08 #4
[snip]
>template <class T>
inline MyAutoPtr<T>::~MyAutoPtr()
{
if(pointee)
{
cout<<"\n\t Deleting pointee..."<<*pointee;
delete pointee;
}
}

delete will perform its own check for 0. It is required to be a null-op in
that case.
Check for 0 is required for printing the debug message. Other then that,
the check should be removed
Oct 13 '08 #5
On Oct 13, 2:36*pm, Yakov Gerlovin <yakov.gerlo...@gmail.comwrote:
Try to define assignment operator without template U parameter:

//assignment operator
MyAutoPtr<T>& operator=(MyAutoPtr<T>& rhs);

Why do you need that 'U' anyway, release should return the pointer to
be passed to reset, so T and U should be equal.
Hi Yakov,

Thanks for the reply!

Yes indeed when I remove the member template function i.e. change the
function as you suggested, it works.
But I don't know whats the problem with the first version.

I should also mention that I'm using visual studio 2008 express
edition.
This be a compiler issue, u reckon?

Thanks!
Oct 13 '08 #6
Thanks for the reply Kai!
Please see the comments below.

On Oct 13, 2:53*pm, Kai-Uwe Bux <jkherci...@gmx.netwrote:
Ankur Arora wrote:
Hi All,
I'm building a sample application that uses a custom auto_ptr
implementation.
The program crashes with the following output:-
Output * * * * * * * (Debug Assertion failed)
----------
* * * * *release called
* * * * *copy constructor
* * * * *aap: ptr2= 10
* * * * *aap: ptr3= 20
* * * * *aap: ptr3= 10
* * * * *aap: exiting app
* * * * *Deleting pointee...10
* * * * *Deleting pointee...-572662307 * * * * (...problem ?)
Code
--------

Just a data point: your code works for me with output

* * * * *release called
* * * * *copy constructor
* * * * *aap: ptr2= 10
* * * * *aap: ptr3= 20
* * * * *Inside operator=
* * * * *Inside operator=, calling reset
* * * * *release called
* * * * *reset called
* * * * *aap: ptr3= 10
* * * * *aap: exiting app
* * * * *Deleting pointee...10

So I just have nits:
#include<iostream>
using namespace std;

It's a bad idea to use using namespace std in a header.
Agreed!
[snip]
template <class T>
inline MyAutoPtr<T>::~MyAutoPtr()
{
* if(pointee)
* {
* * cout<<"\n\t Deleting pointee..."<<*pointee;
* * delete pointee;
* *}
}

delete will perform its own check for 0. It is required to be a null-op in
that case.
I did this since removing this check caused the program to crash, even
though I had made pointee equals to 0 in release(), which was used in
the copy constructor.
I'm using visual studio 2008 express edition. You reckon this is a
complier issue?
>
[snip]
template<class T>
template<class U>
MyAutoPtr<T>& MyAutoPtr<T>::operator=(MyAutoPtr<U>& rhs)
{
* cout<<"\n\t Inside operator=";
* if(this!=&rhs)

This if-clause will not compile when T and U are different.

You could use

* if ( this->pointee == rhs.pointee )

instead (I think).
I saw this example in "More Effective C++" by scott meyers. This was
how its used in that book. Here is a code.

//Interface
template<class T>
class auto_ptr {
public:
explicit auto_ptr(T *p = 0); // see Item 5 for a
// description of
"explicit"
template<class U // copy constructor member
auto_ptr(auto_ptr<U>& rhs); // template (see Item 28):
// initialize a new
auto_ptr
// with any compatible
// auto_ptr
~auto_ptr();
template<class U // assignment operator
auto_ptr<T>& // member template (see
operator=(auto_ptr<U>& rhs); // Item 28): assign from
any
// compatible auto_ptr
T& operator*() const; // see Item 28
T* operator->() const; // see Item 28
T* get() const; // return value of current
// dumb pointer
T* release(); // relinquish ownership of
// current dumb pointer
and
// return its value
void reset(T *p = 0); // delete owned pointer;
// assume ownership of p
private:
T *pointee;
template<class U // make all auto_ptr
classes
friend class auto_ptr<U>; // friends of one another
};

//Implementation
template<class T>
inline auto_ptr<T>::auto_ptr(T *p)
: pointee(p)
{}
template<class T>
inline auto_ptr<T>::auto_ptr(auto_ptr<U>& rhs)
: pointee(rhs.release())
{}
template<class T>
inline auto_ptr<T>::~auto_ptr()
{ delete pointee; }
template<class T>
template<class U>
inline auto_ptr<T>& auto_ptr<T>::operator=(auto_ptr<U>& rhs)
{
if (this != &rhs) reset(rhs.release());
return *this;
}
template<class T>
inline T& auto_ptr<T>::operator*() const
{ return *pointee; }
template<class T>
inline T* auto_ptr<T>::operator->() const
{ return pointee; }
template<class T>
inline T* auto_ptr<T>::get() const
{ return pointee; }
template<class T>
inline T* auto_ptr<T>::release()
{
T *oldPointee = pointee;
pointee = 0;
return oldPointee;
}
template<class T>
inline void auto_ptr<T>::reset(T *p)
{
if (pointee != p) {
delete pointee;
pointee = p;
}
}

Anything wrong with the above ? (would be surprised if there is, as it
came from scott meyers)
Q1. Any problems with the above code ?

It works with g++.
Again, looks like an issue with visual studio 2008 express.
Q2. What is causing operator= not to be called and how to fix it ?

A bug in your compiler?

[snip]

Best

Kai-Uwe Bux
Oct 13 '08 #7
On Oct 13, 10:10*pm, Ankur Arora <ankuraror...@gmail.comwrote:
Thanks for the reply Kai!
Please see the comments below.

On Oct 13, 2:53*pm, Kai-Uwe Bux <jkherci...@gmx.netwrote:
Ankur Arora wrote:
Hi All,
I'm building a sample application that uses a custom auto_ptr
implementation.
The program crashes with the following output:-
Output * * * * * * * (Debug Assertion failed)
----------
* * * * *release called
* * * * *copy constructor
* * * * *aap: ptr2= 10
* * * * *aap: ptr3= 20
* * * * *aap: ptr3= 10
* * * * *aap: exiting app
* * * * *Deleting pointee...10
* * * * *Deleting pointee...-572662307 * * * * (...problem ?)
Code
--------
Just a data point: your code works for me with output
* * * * *release called
* * * * *copy constructor
* * * * *aap: ptr2= 10
* * * * *aap: ptr3= 20
* * * * *Inside operator=
* * * * *Inside operator=, calling reset
* * * * *release called
* * * * *reset called
* * * * *aap: ptr3= 10
* * * * *aap: exiting app
* * * * *Deleting pointee...10
So I just have nits:
#include<iostream>
using namespace std;
It's a bad idea to use using namespace std in a header.

Agreed!
[snip]
template <class T>
inline MyAutoPtr<T>::~MyAutoPtr()
{
* if(pointee)
* {
* * cout<<"\n\t Deleting pointee..."<<*pointee;
* * delete pointee;
* *}
}
delete will perform its own check for 0. It is required to be a null-opin
that case.

I did this since removing this check caused the program to crash, even
though I had made pointee equals to 0 in release(), which was used in
the copy constructor.
I'm using visual studio 2008 express edition. You reckon this is a
complier issue?


[snip]
template<class T>
template<class U>
MyAutoPtr<T>& MyAutoPtr<T>::operator=(MyAutoPtr<U>& rhs)
{
* cout<<"\n\t Inside operator=";
* if(this!=&rhs)
This if-clause will not compile when T and U are different.
You could use
* if ( this->pointee == rhs.pointee )
instead (I think).

I saw this example in "More Effective C++" by scott meyers. This was
how its used in that book. Here is a code.

//Interface
template<class T>
class auto_ptr {
public:
* explicit auto_ptr(T *p = 0); * * * * * * *// see Item5 for a
* * * * * * * * * * * * * * * * * * * * * * // description of
"explicit"
* template<class U* * * * * * * * * * * * // copy constructor member
* auto_ptr(auto_ptr<U>& rhs); * * * * * * * // template (see Item 28):
* * * * * * * * * * * * * * * * * * * * * * // initialize a new
auto_ptr
* * * * * * * * * * * * * * * * * * * * * * // with any compatible
* * * * * * * * * * * * * * * * * * * * * * // auto_ptr
* ~auto_ptr();
* template<class U* * * * * * * * * * * * // assignment operator
* auto_ptr<T>& * * * * * * * * * * * * * * *// member template (see
* operator=(auto_ptr<U>& rhs); * * * * * * *// Item 28): assign from
any
* * * * * * * * * * * * * * * * * * * * * * // compatible auto_ptr
* T& operator*() const; * * * * * * * * * * // see Item 28
* T* operator->() const; * * * * * * * * * *// see Item 28
* T* get() const; * * * * * * * * * * * * * // return value of current
* * * * * * * * * * * * * * * * * * * * * * // dumb pointer
* T* release(); * * * * * * * * * * * * * *// relinquish ownership of
* * * * * * * * * * * * * * * * * * * * * * // current dumb pointer
and
* * * * * * * * * * * * * * * * * * * * * * // return its value
* void reset(T *p = 0); * * * * * * * * * * // delete owned pointer;
* * * * * * * * * * * * * * * * * * * * * * // assume ownership of p
private:
* T *pointee;
template<class U* * * * * * * * * * * * * // make all auto_ptr
classes
friend class auto_ptr<U>; * * * * * * * * * // friends of one another

};

//Implementation
template<class T>
inline auto_ptr<T>::auto_ptr(T *p)
: pointee(p)
{}
template<class T>
* inline auto_ptr<T>::auto_ptr(auto_ptr<U>& rhs)
* : pointee(rhs.release())
* {}
template<class T>
inline auto_ptr<T>::~auto_ptr()
{ delete pointee; }
template<class T>
* template<class U>
* inline auto_ptr<T>& auto_ptr<T>::operator=(auto_ptr<U>& rhs)
* {
* * if (this != &rhs) reset(rhs.release());
* * return *this;
* }
template<class T>
inline T& auto_ptr<T>::operator*() const
{ return *pointee; }
template<class T>
inline T* auto_ptr<T>::operator->() const
{ return pointee; }
template<class T>
inline T* auto_ptr<T>::get() const
{ return pointee; }
template<class T>
inline T* auto_ptr<T>::release()
{
* T *oldPointee = pointee;
* pointee = 0;
* return oldPointee;}

template<class T>
inline void auto_ptr<T>::reset(T *p)
{
* if (pointee != p) {
* * delete pointee;
* * pointee = p;
* }

}

Anything wrong with the above ? (would be surprised if there is, as it
came from scott meyers)
Q1. Any problems with the above code ?
There's a reversion for auto_ptr (IIRC, a article is proviede by Mayer
on
this), adding auto_ptr_ref for conversion, which supports rvalue
initialization for auto_ptr. which is done transparently.

void fun(auto_ptr<Tptr);
fun(auto_ptr(new T)); // rvalue -auto_ptr_ref -auto_ptr
>
It works with g++.

Again, looks like an issue with visual studio 2008 express.
there are two problem with visual C++ 2005 in this issue:
1. as extension, "explicit" does NOT work as standard says.
needs /Za switch to turn it off.

2. auto_ptr_ref use void* rather T*

point 2 is fixed by VS 2008(none expression version,
but I expression version should ship the same lib)
>
Q2. What is causing operator= not to be called and how to fix it ?
A bug in your compiler?
[snip]
--
Best Regards
Barry

Oct 13 '08 #8
On Oct 13, 5:06*pm, Barry <dhb2...@gmail.comwrote:
On Oct 13, 10:10*pm, Ankur Arora <ankuraror...@gmail.comwrote:
Thanks for the reply Kai!
Please see the comments below.
On Oct 13, 2:53*pm, Kai-Uwe Bux <jkherci...@gmx.netwrote:
Ankur Arora wrote:
Hi All,
I'm building a sample application that uses a custom auto_ptr
implementation.
The program crashes with the following output:-
Output * * * * * * * (Debug Assertion failed)
----------
* * * * *release called
* * * * *copy constructor
* * * * *aap: ptr2= 10
* * * * *aap: ptr3= 20
* * * * *aap: ptr3= 10
* * * * *aap: exiting app
* * * * *Deleting pointee...10
* * * * *Deleting pointee...-572662307 * * * * (....problem ?)
Code
--------
Just a data point: your code works for me with output
* * * * *release called
* * * * *copy constructor
* * * * *aap: ptr2= 10
* * * * *aap: ptr3= 20
* * * * *Inside operator=
* * * * *Inside operator=, calling reset
* * * * *release called
* * * * *reset called
* * * * *aap: ptr3= 10
* * * * *aap: exiting app
* * * * *Deleting pointee...10
So I just have nits:
#include<iostream>
using namespace std;
It's a bad idea to use using namespace std in a header.
Agreed!
[snip]
template <class T>
inline MyAutoPtr<T>::~MyAutoPtr()
{
* if(pointee)
* {
* * cout<<"\n\t Deleting pointee..."<<*pointee;
* * delete pointee;
* *}
}
delete will perform its own check for 0. It is required to be a null-op in
that case.
I did this since removing this check caused the program to crash, even
though I had made pointee equals to 0 in release(), which was used in
the copy constructor.
I'm using visual studio 2008 express edition. You reckon this is a
complier issue?
[snip]
template<class T>
template<class U>
MyAutoPtr<T>& MyAutoPtr<T>::operator=(MyAutoPtr<U>& rhs)
{
* cout<<"\n\t Inside operator=";
* if(this!=&rhs)
This if-clause will not compile when T and U are different.
You could use
* if ( this->pointee == rhs.pointee )
instead (I think).
I saw this example in "More Effective C++" by scott meyers. This was
how its used in that book. Here is a code.
//Interface
template<class T>
class auto_ptr {
public:
* explicit auto_ptr(T *p = 0); * * * * * * *// see Item 5 for a
* * * * * * * * * * * * * * * * * ** * * * // description of
"explicit"
* template<class U* * * * * * * * * * * * // copy constructor member
* auto_ptr(auto_ptr<U>& rhs); * * * * * * * // template(see Item 28):
* * * * * * * * * * * * * * * * * ** * * * // initialize a new
auto_ptr
* * * * * * * * * * * * * * * * * ** * * * // with any compatible
* * * * * * * * * * * * * * * * * ** * * * // auto_ptr
* ~auto_ptr();
* template<class U* * * * * * * * * * * * // assignment operator
* auto_ptr<T>& * * * * * * * * * * * * * * *// member template (see
* operator=(auto_ptr<U>& rhs); * * * * * * *// Item 28): assign from
any
* * * * * * * * * * * * * * * * * ** * * * // compatible auto_ptr
* T& operator*() const; * * * * * * * * * * // see Item 28
* T* operator->() const; * * * * * * * * * *// see Item 28
* T* get() const; * * * * * * * * * * * * *// return value of current
* * * * * * * * * * * * * * * * * ** * * * // dumb pointer
* T* release(); * * * * * * * * * * * * * * // relinquish ownership of
* * * * * * * * * * * * * * * * * ** * * * // current dumb pointer
and
* * * * * * * * * * * * * * * * * ** * * * // return its value
* void reset(T *p = 0); * * * * * * * * * * // delete owned pointer;
* * * * * * * * * * * * * * * * * ** * * * // assume ownership of p
private:
* T *pointee;
template<class U* * * * * * * * * * * * * // make all auto_ptr
classes
friend class auto_ptr<U>; * * * * * * * * * // friends of one another
};
//Implementation
template<class T>
inline auto_ptr<T>::auto_ptr(T *p)
: pointee(p)
{}
template<class T>
* inline auto_ptr<T>::auto_ptr(auto_ptr<U>& rhs)
* : pointee(rhs.release())
* {}
template<class T>
inline auto_ptr<T>::~auto_ptr()
{ delete pointee; }
template<class T>
* template<class U>
* inline auto_ptr<T>& auto_ptr<T>::operator=(auto_ptr<U>& rhs)
* {
* * if (this != &rhs) reset(rhs.release());
* * return *this;
* }
template<class T>
inline T& auto_ptr<T>::operator*() const
{ return *pointee; }
template<class T>
inline T* auto_ptr<T>::operator->() const
{ return pointee; }
template<class T>
inline T* auto_ptr<T>::get() const
{ return pointee; }
template<class T>
inline T* auto_ptr<T>::release()
{
* T *oldPointee = pointee;
* pointee = 0;
* return oldPointee;}
template<class T>
inline void auto_ptr<T>::reset(T *p)
{
* if (pointee != p) {
* * delete pointee;
* * pointee = p;
* }
}
Anything wrong with the above ? (would be surprised if there is, as it
came from scott meyers)
Q1. Any problems with the above code ?

There's a reversion for auto_ptr (IIRC, a article is proviede by Mayer
on
this), adding auto_ptr_ref for conversion, which supports rvalue
initialization for auto_ptr. which is done transparently.

void fun(auto_ptr<Tptr);
fun(auto_ptr(new T)); // rvalue -auto_ptr_ref -auto_ptr
It works with g++.
Again, looks like an issue with visual studio 2008 express.

there are two problem with visual C++ 2005 in this issue:
1. as extension, "explicit" does NOT work as standard says.
* *needs /Za switch to turn it off.

2. auto_ptr_ref use void* rather T*

point 2 is fixed by VS 2008(none expression version,
but I expression version should ship the same lib)
Q2. What is causing operator= not to be called and how to fix it ?
A bug in your compiler?
[snip]

--
Best Regards
Barry
Thanks Barry.
Oct 15 '08 #9
Barry wrote:
[...]
There's a reversion for auto_ptr (IIRC, a article is proviede by Mayer
on
this), adding auto_ptr_ref for conversion, which supports rvalue
initialization for auto_ptr. which is done transparently.
The guy's name is Scott Meyers and the article is here:
http://www.aristeia.com/BookErrata/auto_ptr-update.html
[...]
there are two problem with visual C++ 2005 in this issue:
1. as extension, "explicit" does NOT work as standard says.
needs /Za switch to turn it off.
Do you have a repro for this? I'd be very interested.
[...]
Barry
Schobi
Oct 15 '08 #10
On Oct 15, 11:22*pm, Hendrik Schober <spamt...@gmx.dewrote:
Barry wrote:
[...]
There's a reversion for auto_ptr (IIRC, a article is proviede by Mayer
on
this), adding auto_ptr_ref for conversion, which supports rvalue
initialization for auto_ptr. which is done transparently.

* The guy's name is Scott Meyers and the article is here:
* *http://www.aristeia.com/BookErrata/auto_ptr-update.html
[...]
there are two problem with visual C++ 2005 in this issue:
1. as extension, "explicit" does NOT work as standard says.
* *needs /Za switch to turn it off.

* Do you have a repro for this? I'd be very interested.
#include <memory>

int main()
{
std::auto_ptr<intp1 = new int(10); // this shouldn't work
std::auto_ptr<intp2(new int(10)); // should be like this!
}

=================
d:\>cl /EHsc test.cpp

Compile successfully!
=================

d:\>cl /EHsc /Za test.cpp
cl /EHsc /Za test.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.42
for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.

test.cpp
test.cpp(5) : error C2440: 'initializing' : cannot convert from 'int
*' to 'std::auto_ptr<_Ty>'
with
[
_Ty=int
]
Constructor for class 'std::auto_ptr<_Ty>' is declared
'explicit'
with
[
_Ty=int
]

===========================

--
Best Regards
Barry
Oct 17 '08 #11
Barry wrote:
On Oct 15, 11:22 pm, Hendrik Schober <spamt...@gmx.dewrote:
>Barry wrote:
>>[...]
There's a reversion for auto_ptr (IIRC, a article is proviede by Mayer
on
this), adding auto_ptr_ref for conversion, which supports rvalue
initialization for auto_ptr. which is done transparently.
The guy's name is Scott Meyers and the article is here:
http://www.aristeia.com/BookErrata/auto_ptr-update.html
>>[...]
there are two problem with visual C++ 2005 in this issue:
1. as extension, "explicit" does NOT work as standard says.
needs /Za switch to turn it off.
Do you have a repro for this? I'd be very interested.

#include <memory>

int main()
{
std::auto_ptr<intp1 = new int(10); // this shouldn't work
std::auto_ptr<intp2(new int(10)); // should be like this!
}
[...]
Thanks.
It doesn't seem to be a compielr bug, though, as a simple
test with my own class makes the first line fail.

Schobi
Oct 18 '08 #12
On Oct 17, 6:16*pm, Hendrik Schober <spamt...@gmx.dewrote:
Barry wrote:
On Oct 15, 11:22 pm, Hendrik Schober <spamt...@gmx.dewrote:
Barry wrote:
[...]
There's a reversion for auto_ptr (IIRC, a article is proviede by Mayer
on
this), adding auto_ptr_ref for conversion, which supports rvalue
initialization for auto_ptr. which is done transparently.
* The guy's name is Scott Meyers and the article is here:
* *http://www.aristeia.com/BookErrata/auto_ptr-update.html
>[...]
there are two problem with visual C++ 2005 in this issue:
1. as extension, "explicit" does NOT work as standard says.
* *needs /Za switch to turn it off.
* Do you have a repro for this? I'd be very interested.
#include <memory>
int main()
{
* * std::auto_ptr<intp1 = new int(10); // this shouldn't work
* * std::auto_ptr<intp2(new int(10)); *// should be like this!
}
[...]

* Thanks.
* It doesn't seem to be a compielr bug, though, as a simple
* test with my own class makes the first line fail.
Maybe some Serive Package fix this.
I tried the code on Dinkumware
http://www.dinkumware.com/exam/default.aspx
it fails too.

--
Best Regards
Barry
Oct 19 '08 #13
On Oct 13, 2:58*pm, Kai-Uwe Bux <jkherci...@gmx.netwrote:
Yakov Gerlovin wrote:
Try to define assignment operator without template U
parameter:
//assignment operator
MyAutoPtr<T>& operator=(MyAutoPtr<T>& rhs);
Why do you need that 'U' anyway, release should return the
pointer to be passed to reset, so T and U should be equal.
He needs it to support polymorphism. When D is derived from B,
MyAutoPtr<Bshould be constructible and assignable from
MyAutoPtr<D>.
But the OP could define copy-constructor and assignment
operator from T separately. For the copy-constructor, I recall
that this is needed. I am not sure if it is needed for the
assignment operator.
If I understand the context correctly, it is. A template
operator= will never stop the compiler from generating its
default copy operator=.

--
James Kanze (GABI Software) email:ja*********@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
Oct 19 '08 #14
On Oct 13, 1:58*pm, Ankur Arora <ankuraror...@gmail.comwrote:
I'm building a sample application that uses a custom auto_ptr
implementation. The program crashes with the following
output:-
Output * * * * * * * (Debug Assertion failed)
----------
* * * * *release called
* * * * *copy constructor
* * * * *aap: ptr2= 10
* * * * *aap: ptr3= 20
* * * * *aap: ptr3= 10
* * * * *aap: exiting app
* * * * *Deleting pointee...10
* * * * *Deleting pointee...-572662307 * * * * (...problem ?)
Code
--------
#include<iostream>
using namespace std;
// MyAutoPtr Interface
template <class T>
class MyAutoPtr
{
* * * * public:
* * * * * * * * explicit MyAutoPtr(T* ptr=0);
* * * * * * * * ~MyAutoPtr();
* * * * * * * * template <class U>
* * * * * * * * MyAutoPtr(MyAutoPtr<U*rhs);
* * * * * * * * //copy constructor member template, initialize
//this member pointer
//with any other compatible auto_ptr
* * * * * * * * template <class U>
* * * * * * * * MyAutoPtr(MyAutoPtr<U>& rhs);
This is NOT a copy constructor, according to the standard, and
it will not prevent the compiler from generating its default
copy constructor.
* * * * * * * * //assignment operator
* * * * * * * * template <class U>
* * * * * * * * MyAutoPtr<T>& operator=(MyAutoPtr<U>& rhs);
And this is NOT a copy assignment operator, and will not prevent
the compiler from generating its own.

Note that in the two cases above, the compiler will generate its
own versions of the functions, but they will have an argument
type MyAutoPtr<Tconst&; not non-const. Which means that in
some cases, when copying, the template version you provide will
be called, rather than the official copy constructor or copy
assignment operator. (I know it sounds wierd, but it's really
rather logical: overload resolution is applied, regardless of
whether the context involves "copying" or not. Template
functions are never considered "copy" operators, but if overload
resolution chooses one, that's what gets called.)
* * * * * * * * //relinquish ownership
* * * * * * * * T* release();
* * * * * * * * T* get() const;
* * * * * * * * //reset the auto_ptr, delete pointee, assume ownership of p
* * * * * * * * void reset(T* ptr=0);
* * * * * * * * T& operator*() const;
* * * * * * * * T* operator->() const;
* * * * private:
* * * * * * * * T* pointee;
* * * * * * * * //template <class U>
* * * * * * * * //friend class MyAutoPtr<U>;
};
//Implementation
[... just does the obvious things]
void main()
Shouldn't compile:-).
{
* * * * MyAutoPtr<intintp(new int(10));
* * * * MyAutoPtr<intintp2(intp);
* * * * MyAutoPtr<intintp3(new int(20));
Now comes the fun part. Note that all of your instances are for
the same type. So the compiler generated functions will come
into consideration.

Note too that when intp and intp3 go out of scope, they're going
to use a non-array delete on memory that was allocated with an
array new. Undefined behavior.
* * * * //cout<<"ptr1= "<<*intp;
* * * * cout<<"\n\t aap: ptr2= "<<*intp2;
* * * * cout<<"\n\t aap: ptr3= "<<*intp3;
* * * * intp3 = intp2; * * *// ==============================*1

* * * * cout<<"\n\t aap: ptr3= "<<*intp3;
* * * * cout<<"\n\t aap: exiting app";
}
It seems, on debugging, that class's custom operator= is
somehow not been called at 1 and hence a problem while
destructing.
This would be a compiler error, but a subtle one. Since intp2
is a non-const lvalue, overload resolution should choose your
template'd operator= over the compiler generated one (which is
none the less present). Given that the context is copy, it
looks like the compiler is using copy assignment operator,
without doing full overload resolution.
(since delete
is being called twice on the same pointer)
--------------------------------------------
Q1. Any problems with the above code ?
IMHO, yes. The fact that you've let the compiler generate its
default versions will lead to runtime errors which may be
difficult to check. (Basically, you can assign a const or a
temporary MyAutoPtr, with the wrong semantics.) At the very
least, you should declare and define the copy constructor and
the assignment operator you want: non-template functions taking
a MyAutoPtr<T>& (and not the MyAutoPtr<Tconst& that the
compiler will generate here).
Q2. What is causing operator= not to be called and how to fix
it ?
It looks like a compiler error, but I suspect that my
recommendations concerning Q1 will also fix it.

--
James Kanze (GABI Software) email:ja*********@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
Oct 19 '08 #15
Barry wrote:
On Oct 17, 6:16 pm, Hendrik Schober <spamt...@gmx.dewrote:
>Barry wrote:
>>On Oct 15, 11:22 pm, Hendrik Schober <spamt...@gmx.dewrote:
Barry wrote:
[...]
>>#include <memory>
int main()
{
std::auto_ptr<intp1 = new int(10); // this shouldn't work
std::auto_ptr<intp2(new int(10)); // should be like this!
}
[...]
It doesn't seem to be a compielr bug, though, as a simple
test with my own class makes the first line fail.

Maybe some Serive Package fix this.
I tried the code on Dinkumware
http://www.dinkumware.com/exam/default.aspx
it fails too.
Um, I think I've been unclear. The first line compiles with
'std::auto_ptr<>' but this fails:

class test {
public:
explicit test(void*) {}
};

int main()
{
´ test t1 = new int; // fails
test t2(new int); // compiles
return 0;
}
So it's probably not a problem of the compiler, but of the
std lib implementation that came with it.
Best Regards
Barry
Schobi

P.S.: BTW, never put pointers to arrays into 'std::auto_ptr<>'.
Oct 20 '08 #16
On Oct 21, 2:26*am, Hendrik Schober <spamt...@gmx.dewrote:
Barry wrote:
On Oct 17, 6:16 pm, Hendrik Schober <spamt...@gmx.dewrote:
Barry wrote:
On Oct 15, 11:22 pm, Hendrik Schober <spamt...@gmx.dewrote:
Barry wrote:
[...]
>#include <memory>
int main()
{
* * std::auto_ptr<intp1 = new int(10); // this shouldn't work
* * std::auto_ptr<intp2(new int(10)); *// should be like this!
}
[...]
* It doesn't seem to be a compielr bug, though, as a simple
* test with my own class makes the first line fail.
Maybe some Serive Package fix this.
I tried the code on Dinkumware
http://www.dinkumware.com/exam/default.aspx
it fails too.

* Um, I think I've been unclear. The first line compiles with
* 'std::auto_ptr<>' but this fails:

* * class test {
* * public:
* * * explicit test(void*) {}
* * };

* * int main()
* * {
´ * *test t1 = new int; // fails
* * * test t2(new int); *// compiles
* * * return 0;
* * }

* So it's probably not a problem of the compiler, but of the
* std lib implementation that came with it.
yes, it only comes specially with auto_ptr
>
Best Regards
Barry

* Schobi

* P.S.: BTW, never put pointers to arrays into 'std::auto_ptr<>'.
I think you were confused the syntax of "new int(10)" with "new
int[10]"
it mean "new an integer with initial value 10"
--
Best Regards
Barry
Oct 21 '08 #17
Barry wrote:
[...]
> P.S.: BTW, never put pointers to arrays into 'std::auto_ptr<>'.

I think you were confused the syntax of "new int(10)" with "new
int[10]"
it mean "new an integer with initial value 10"
Yes, I was. Sorry for that brainfart.
Barry
Schobi
Oct 21 '08 #18

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

Similar topics

3
by: SerGioGio | last post by:
Hello ! When a ref. counted smart pointer (template) class is available (like boost::shared_ptr), is there any (semantic) reason to still use std::auto_ptr rather than this smart pointer ? Or...
9
by: BekTek | last post by:
How do you think? and why?
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...
5
by: Evgeny | last post by:
Hi, all! I try to convert my existing code written in VC6 to VC7 and have some problem with stl auto pointer template. class CColumn; #include <memory> typedef auto_ptr<CMyBase> CMyBasePtr; ...
14
by: Andrew | last post by:
Hello all: After spending some time figuring out auto_ptr class' implementation, I decided to write a small article detailing its use of the auto_ptr_ref proxy class to enable construction and...
10
by: red floyd | last post by:
It seems that the use of auto_ptr<> is discouraged in many places in favor of boost::shared_ptr<> (or tr1::shared_ptr<>). But consider a PIMPL idiom, where there is a strict 1-1 relationship...
9
by: dragoncoder | last post by:
Hi all, I am trying to understand the auto_ptr_ref role in the implementation of auto_ptr<>. I read the information on net but still not 100% sure of it. My plan is as follows. 1. To see the...
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 ...
18
by: Barry | last post by:
struct A { void Print() const { cout << "Print" << endl; } }; auto_ptr<AGet() {
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
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...

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.