Is it the BUG of VC 7.1

D

Darkay Li

I have try to create an allocator like follow:
// the type of allocator must be some kind of pointer
template <class Type>
class PointerAllocator : public std::allocator<Type>
{
public:
typedef std::allocator<Type> BaseClass;

public:
void destroy(pointer ptr)
{
delete (*ptr); // "Type" must be a pointer of object
BaseClass::destroy(ptr);
}
};

My allocator derive from the std::allocator, and just rewrite the destroy
method, to delete the object which the pointer pointer at.
and then I create three containers:
template <class Type>
class PointerList : public std::list<Type, PointerAllocator<Type> >
{
};

template <class Type>
class PointerDeque : public std::deque<Type, PointerAllocator<Type> >
{
};

template<class Key, class Type, class Traits = less<Key> >
class PointerMap : public std::map<Key, Type, Traits,
PointerAllocator<Type> >
{
};
These container can store pointer of the object and free the object it self.

at last I write my test code:
int main(int argc, char* argv[])
{
PointerDeque<int *> pd;
pd.push_back(new int(10));
int *p = pd.front();
cout << *p << endl;

PointerList<int *> pl;
pl.push_back(new int (10));
cout << **pl.begin() << endl;

PointerMap<int , int *> pm;
pm[1] = new int(10);
cout << *pm[1] << endl;

return 0;
}
everything OK when I using VC6 and SGI's STL(both VC6 and VC7.1), but when I
compile the test code with VC7.1(P.J STL) I got error (error message show in
the end). I check the error and find it's the problem of deque's iterator.
In VC7.1 the iterator of deque definition is:
class iterator
: public const_iterator
{ // iterator for mutable deque
public:
//......
iterator(size_type _Off, const deque<_Ty, _Alloc> *_Pdeque)
: const_iterator(_Off, _Pdeque)
{ // construct with offset _Off in *_Pdeque
}
}
the constructor prototype of iterator is :
iterator(size_type _Off, const deque<_Ty, _Alloc> *_Pdeque)
and I find it's different from const_iterator's constructor prototype:
const_iterator(size_type _Off, const _Myt *_Pdeque)

Why not use the same definiation of const_iterator?
when I modify the constructor of iterator as the same with const_iterator.
the all my test code compile pass(and run OK).
Is it the BUG of VC7.1 ?

The compile error:
Compiling...
queueTest.cpp
o:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\deque(441) :
error C2665: 'std::deque<_Ty,_Ax>::iterator::iterator' : none of the 3
overloads can convert parameter 2 from type 'std::deque<_Ty,_Ax> *const '
with
[
_Ty=int *,
_Ax=stk::pointerAllocator<int *>
]
and
[
_Ty=int *,
_Ax=stk::pointerAllocator<int *>
]
o:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\deque(241): could be
'std::deque<_Ty,_Ax>::iterator::iterator(std::deque<_Ty,_Ax>::size_type,cons
t std::deque<_Ty,std::deque<_Ty,_Ax>::_Alloc> *)'
with
[
_Ty=int *,
_Ax=stk::pointerAllocator<int *>
]
while trying to match the argument list
'(std::deque<_Ty,_Ax>::size_type, std::deque<_Ty,_Ax> *const )'
with
[
_Ty=int *,
_Ax=stk::pointerAllocator<int *>
]
and
[
_Ty=int *,
_Ax=stk::pointerAllocator<int *>
]
o:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\deque(440) : while compiling class-template member function
'std::deque<_Ty,_Ax>::iterator std::deque<_Ty,_Ax>::begin(void)'
with
[
_Ty=int *,
_Ax=stk::pointerAllocator<int *>
]
d:\SysDir\Documents\Visual Studio
Projects\queueTest\pointercontainer.h(48) : see reference to class template
instantiation 'std::deque<_Ty,_Ax>' being compiled
with
[
_Ty=int *,
_Ax=stk::pointerAllocator<int *>
]
d:\SysDir\Documents\Visual Studio
Projects\queueTest\queueTest.cpp(13) : see reference to class template
instantiation 'stk::pointerDeque<Type>' being compiled
with
[
Type=int *
]
 
T

tom_usenet

I have try to create an allocator like follow:
// the type of allocator must be some kind of pointer
template <class Type>
class PointerAllocator : public std::allocator<Type>
{
public:
typedef std::allocator<Type> BaseClass;

public:
void destroy(pointer ptr)
{
delete (*ptr); // "Type" must be a pointer of object
BaseClass::destroy(ptr);
}
};

My allocator derive from the std::allocator, and just rewrite the destroy
method, to delete the object which the pointer pointer at.

What makes you think that your destroy member will be called? If you
allocator is rebound, the rebound type will be a std::allocator, not
your allocator, and hence your destroy won't be used.

In fact, your allocator doesn't conform to allocator requirements:
and then I create three containers:
template <class Type>
class PointerList : public std::list<Type, PointerAllocator<Type> >
{
};

template <class Type>
class PointerDeque : public std::deque<Type, PointerAllocator<Type> >
{
};

template<class Key, class Type, class Traits = less<Key> >
class PointerMap : public std::map<Key, Type, Traits,
PointerAllocator<Type> >
{
};
These container can store pointer of the object and free the object it self.

Did you actually test this? You may find that your destroy member is
never called.
at last I write my test code:
int main(int argc, char* argv[])
{
PointerDeque<int *> pd;
pd.push_back(new int(10));
int *p = pd.front();
cout << *p << endl;

PointerList<int *> pl;
pl.push_back(new int (10));
cout << **pl.begin() << endl;

PointerMap<int , int *> pm;
pm[1] = new int(10);
cout << *pm[1] << endl;

return 0;
}
everything OK when I using VC6 and SGI's STL(both VC6 and VC7.1),

When you say ok, was your destroy function actually called?

but when I
compile the test code with VC7.1(P.J STL) I got error (error message show in
the end). I check the error and find it's the problem of deque's iterator.
In VC7.1 the iterator of deque definition is:
class iterator
: public const_iterator
{ // iterator for mutable deque
public:
//......
iterator(size_type _Off, const deque<_Ty, _Alloc> *_Pdeque)
: const_iterator(_Off, _Pdeque)
{ // construct with offset _Off in *_Pdeque
}
}
the constructor prototype of iterator is :
iterator(size_type _Off, const deque<_Ty, _Alloc> *_Pdeque)
and I find it's different from const_iterator's constructor prototype:
const_iterator(size_type _Off, const _Myt *_Pdeque)

Why not use the same definiation of const_iterator?

Well, according to the allocator requirements, _Myt and deque<Ty,
_Alloc> are the same type, so the implementation is allowed to use
them interchangeably.
when I modify the constructor of iterator as the same with const_iterator.
the all my test code compile pass(and run OK).
Is it the BUG of VC7.1 ?

No. Your approach isn't going to work. For a start you will have
double deletion problems. Instead I would recommend either writing a
container adapter for pointer holding containers that deletes pointers
when necessary, or use a container<shared_ptr<T> >. e.g.

template <class Cont>
class pointer_container
{
protected:
Cont c;
public:
typedef typename Cont::iterator iterator;
//...
typedef typename Cont::value_type value_type;



void pop_back()
{
delete c.back();
c.pop_back();
}

//etc.
};

Remember that mutating algorithms (like remove_if) will still cause
problems.

Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
 

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,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top