Copy link to clipboard
Copied
According to InDesign SDK, there is no destructor declared IDType class, and the UID is a typedef "typedef IDType<UID_tag> UID".
What will happen if an UID type variable be destroyed?
The problem I'm facing is, e.g.
// My code is bellowing:
class MyClass{
public:
MyClass(int key):fKey(key) {}
const UID GetKey() const { return fKey; }
// some other members but destructor.
private:
UID fKey;
};
bool operator==(const MyClass& lh, const MyClass& rh)
{
cout<<lh.GetKey().Get()<<" "<<rh.GetKey().Get()<<endl;
return (lh.GetKey() == rh.GetKey());
}
list<MyClass> myList;
// insert some items into myList. The items are with key 1, 2, 3, 4 and 5
MyClass val(3);
cout<<"Before remove"<<endl;
myList.remove(val);
cout<<"After remove"<<endl;
Before remove
1 3 2 3 3 3 4 29 5 29 After remove
As you see, after "3 3" the uid was changed.
It happened on MAC. Any idea?
Did i miss something? Or there is any rule i need to follow while using container list on MAC?
PS: Following is the source code of list::remove() on MAC.
template<typename _Tp, typename _Alloc> void list<_Tp, _Alloc>::
remove(const value_type& __value)
{
iterator __first = begin();
iterator __last = end();
while (__first != __last)
{
iterator __next = __first;
++__next;
if (*__first == __value)
_M_erase(__first);
__first = __next;
}
}
Copy link to clipboard
Copied
Sounds more like a problem of your list<>::remove implementation that is only showing with gcc. You're wrongly assuming that after erase your iterator "next" is still valid.
What happens if you do the same with fKey as int32?
Besides there is good old UIDList ...
Dirk
Copy link to clipboard
Copied
I posted just a sample of my code, I tested with it, there was no problem i am asking here.
But i have no idea what cause my problem.
In face, in my code, the class member not only UID but also a PMString there. When removing a item form list, after it matches the condition "if (*__first == __value)" first time, the value of object __value is changed, both the UID member and PMString member. Any idea?
Copy link to clipboard
Copied
Besides, the same code works well on Windows.
Copy link to clipboard
Copied
In addition, when execute "_M_erase(__first);", the __first and &__value have the same memory address, could that be the reason?
I mean the object __value is destroyed after deallocate __first. Just my guess.
Copy link to clipboard
Copied
I think i have got the reason, let's see the source code on Windows from MS vc++.
void remove(const _Ty& _Val_arg)
{ // erase each element matching _Val
/* Dinkumware makes a copy of _Val_arg in case it's removed along the way, i.e.
* when the user pass an element of the list as _Val_arg.
*
* We believe that the signature of std::list::remove should be changed
* from remove(const _Ty&) to remove(_Ty) to explicitly indicate that a copy is involved.
*/
const _Ty _Val = _Val_arg; // in case it's removed along the way
iterator _Last = end();
for (iterator _First = begin(); _First != _Last; )
if (*_First == _Val)
_First = erase(_First);
else
++_First;
}
Please pay attention to statement "const _Ty _Val = _Val_arg;" ant its comment.
The problem i faced is, the argument that passed into list::remove() is the object from list.
That means on MAC, the statement "_M_erase(__first);" would destroy the object __first pointing to, unfortunately, __first is pointing to __value.
Therefore, after "_M_erase(__first);", the __value is destroyed. Make a copy to be the argument to remove items from list is the solution.
Find more inspiration, events, and resources on the new Adobe Community
Explore Now