By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,750 Members | 1,187 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,750 IT Pros & Developers. It's quick & easy.

Is it the BUG of VC 7.1

P: n/a
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::dequ e<_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 *
]

Jul 22 '05 #1
Share this Question
Share on Google+
1 Reply


P: n/a
On Fri, 19 Dec 2003 09:27:23 +0800, "Darkay Li"
<da*******@hotmail.com> wrote:
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:
Alloc::rebind<U>::other::rebind<T>::other has to be the same as Alloc
(for T). This isn't the case with yours, hence the problems.
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 Icompile 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
Jul 22 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.