Re: A Sample auto_ptr implementation
On Oct 13, 1:58 pm, Ankur Arora <ankuraror...@gmail.com> wrote:
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 (...prob=
lem ?)
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, initi=
alize
//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>& r=
hs);
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<T> const&; 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, ass=
ume 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<int> intp(new int(10));
MyAutoPtr<int> intp2(intp);
MyAutoPtr<int> intp3(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<T> const& 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:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34