CPtrList
-
Hi, I am trying to iterate and delete the elements (assuming atleast 1 element) in a CptrList with this: void *pPt = NULL; POSITION pos = NULL; for (pos = m_points.GetHeadPosition(); !m_points.IsEmpty(); m_points.GetNext(pos)) { // TRACE("pos: %d, %d\n", pos, NULL); pPt = m_points.GetAt(pos); m_points.RemoveAt(pos); delete pPt; } TRACE shows that pos is not equal to NULL as it should be after the last element has been seen. So pos != NULL check does not work contrary to the MSDN Library documentation. THIS IS ONE PROBLEM. The OTHER is even if there are more than 1 elements the second element returned by GetAt is not "valid" (0xcdcdcdcd) and RemoveAt asserts. Any clues? Regards Mahendra
-
Hi, I am trying to iterate and delete the elements (assuming atleast 1 element) in a CptrList with this: void *pPt = NULL; POSITION pos = NULL; for (pos = m_points.GetHeadPosition(); !m_points.IsEmpty(); m_points.GetNext(pos)) { // TRACE("pos: %d, %d\n", pos, NULL); pPt = m_points.GetAt(pos); m_points.RemoveAt(pos); delete pPt; } TRACE shows that pos is not equal to NULL as it should be after the last element has been seen. So pos != NULL check does not work contrary to the MSDN Library documentation. THIS IS ONE PROBLEM. The OTHER is even if there are more than 1 elements the second element returned by GetAt is not "valid" (0xcdcdcdcd) and RemoveAt asserts. Any clues? Regards Mahendra
As soon as you remove the element, you invalidate the position. Here's a better way of doing it:
{ void *pPt = NULL; POSITION pos = NULL; for (pos = m_points.GetHeadPosition(); pos != NULL; m_points.GetNext(pos)) { // TRACE("pos: %d, %d\n", pos, NULL); pPt = m_points.GetAt(pos); delete pPt; } // Now we have a list full of invalid pointers, so remove them all m_points.RemoveAll(); }
"Fish and guests stink in three days." - Benjamin Franlkin -
As soon as you remove the element, you invalidate the position. Here's a better way of doing it:
{ void *pPt = NULL; POSITION pos = NULL; for (pos = m_points.GetHeadPosition(); pos != NULL; m_points.GetNext(pos)) { // TRACE("pos: %d, %d\n", pos, NULL); pPt = m_points.GetAt(pos); delete pPt; } // Now we have a list full of invalid pointers, so remove them all m_points.RemoveAll(); }
"Fish and guests stink in three days." - Benjamin FranlkinBut is this ok - (re)moving from the tail end if a sub-sequence has to be removed and RQUIRES using RemoveAt. This seems to works: for (pos = m_points.GetTailPosition(); !m_points.IsEmpty(); m_points.GetPrev(pos)) { pPt = m_points.GetAt(pos); delete pPt; m_points.RemoveAt(pos); } pos is still not NULL in the end though! Or like in the MSDNL RemoveAt help!: POSITION pos1 = NULL; POSITION pos2 = NULL; for (pos1 = m_points.GetHeadPosition(); (pos2 = pos1) != NULL; ) { m_points.GetNext(pos1); pPt = m_points.GetAt(pos2); delete pPt; m_points.RemoveAt(pos2); } Due Regards Mahendra
-
Hi, I am trying to iterate and delete the elements (assuming atleast 1 element) in a CptrList with this: void *pPt = NULL; POSITION pos = NULL; for (pos = m_points.GetHeadPosition(); !m_points.IsEmpty(); m_points.GetNext(pos)) { // TRACE("pos: %d, %d\n", pos, NULL); pPt = m_points.GetAt(pos); m_points.RemoveAt(pos); delete pPt; } TRACE shows that pos is not equal to NULL as it should be after the last element has been seen. So pos != NULL check does not work contrary to the MSDN Library documentation. THIS IS ONE PROBLEM. The OTHER is even if there are more than 1 elements the second element returned by GetAt is not "valid" (0xcdcdcdcd) and RemoveAt asserts. Any clues? Regards Mahendra
One problem I see in your example is the line
delete pPt;
. This line won't work correctly. SincepPt
is avoid
pointer, the compiler won't know whichdelete
operator and destructor to call. This will lead to memory leaks and possibly heap corruption. A better approach would be:while (!m_points.IsEmpty()) {
MyType *pPt = (MyType *)m_points.RemoveHead();
delete pPt;
}In this case,
MyType
is the type of the value pointed to by members of the list. If you use aCTypedPtrList<>
, you can delete the contents of a list more simply as follows:CTypedPtrList<MyType> m_points;
//...
while (!m_points.IsEmpty()) {
delete m_points.RemoveHead();
}Using
CTypedPtrList
you don't need type casts.
Software Zen:
delete this;