tags:

views:

85

answers:

1

I'm looking at this, where m_Rows is a CAtlList:

void CData::RemoveAll()
{
    size_t cItems = m_Rows.GetCount();
    POSITION Pos = m_Rows.GetHeadPosition();

    while(Pos != 0)
    {
        CItem* pItem = m_Rows.GetAt(Pos);

        if (pItem != 0)
            delete pItem;

        POSITION RemoveablePos = Pos;
        pItem = m_Rows.GetNext(Pos);

        m_Rows.RemoveAt(RemoveablePos);
    }
}

and am wondering if there's potential that the RemoveAt call may invalidate Pos?

+1  A: 

According to the documentation, CAtlList behaves like a double linked list, so removing one list item should not invalidate the pointers to other items. The POSITION type references the memory location of a list item directly:

Most of the CAtlList methods make use of a position value. This value is used by the methods to reference the actual memory location where the elements are stored, and should not be calculated or predicted directly.

It seems this is not the case in atlcoll.h:

template< typename E, class ETraits >
void CAtlList< E, ETraits >::RemoveAt( POSITION pos )
{
ATLASSERT_VALID(this);
ATLENSURE( pos != NULL );

CNode* pOldNode = (CNode*)pos;

// remove pOldNode from list
if( pOldNode == m_pHead )
{
 m_pHead = pOldNode->m_pNext;
}
else
{
 ATLASSERT( AtlIsValidAddress( pOldNode->m_pPrev, sizeof(CNode) ));
 pOldNode->m_pPrev->m_pNext = pOldNode->m_pNext;
}
if( pOldNode == m_pTail )
{
 m_pTail = pOldNode->m_pPrev;
}
else
{
 ATLASSERT( AtlIsValidAddress( pOldNode->m_pNext, sizeof(CNode) ));
 pOldNode->m_pNext->m_pPrev = pOldNode->m_pPrev;
}
FreeNode( pOldNode );
}
Sebastian
Thanks for finding that. I'm not sure that statement in the documentation actually answers my question. I mean, it's possible that when a RemoveAt is performed that other elements could be moved in memory by the operation. I'm guessing other elements don't get moved, but wanted to be sure this code is correct.
Scott Langham
That is a valid point. I didn't feel the documenation was very precise either. I think the code excerpt settles it though :-)
Sebastian