CMapStringToString myMap;//假设已经存入数据POSITION pos = myMap.GetStartPosition();
while(pos)
{
    CString s1;
    CString s2;
    myMap.GetNextAssoc(pos, s1, s2);
    CString s3;
    if(myMap.Lookup(s2,s3) && s3 == s1)
    {
         myMap.RemoveKey(s1);
         myMap.RemoveKey(s2);
    }}由于上面的RemoveKey操作是在遍历里面的,而且还会将当前的Key删除,这样子的遍历能便利到最后吗?
如果可以的话,能不能请各位大虾说一下原因(因为我总觉得pos地址会出错,比如pos中的指针正好指向的是Key为S2的数据的时候,不知道是不是我想多了)
如果不行的吧,以上这种操作应该怎么去实现呢?

解决方案 »

  1.   

    删除节点后,pos要移动啊
      

  2.   

    GetNextAssoc会把pos指向下一个地址,而你删除的是当前的节点。所以可以遍历到最后
      

  3.   

    是的  因为我不是有删除两个节点?
    如果万一我删除的下一个节点正好是pos所指向的节点呢?
      

  4.   

    s1应该是key,s2是value,他们两个才是一个节点
    2. 你自己要保证不会删除下一个节点.
      

  5.   

    我有myMap.RemoveKey(s2);
    怎样保证删除的节点不是下一个节点?
    这个时候是要找POS节点上的key内容,如果是被删除节点就找下个节点?
    我上面的例子只是两个值,万一是很多值的怎么进行处理?(就是我一次删除好多节点,但是每个都恰恰好是上个节点的下个节点呢? (是不是我想多了 ?))
      

  6.   

    POSITION的实质,就是一个结点指针,Map里的GetNextAsso就是把CAssoc*(我不太记得了)转成了(POSITION)。它是直接强转的。
      

  7.   

    没人了?我是不是可以这样理解,POSITION pos中存储的是地址,执行GetNextAssoc之后,存储的就是下一个地址,如果此时在代码中恰好删除了pos存储下的内容,那么此时的pos就是无效的了。循环也会出错,因为while判断pos的时候仍然为真,但事实上是无效的,导致执行GetNextAssoc就会出错。
      

  8.   

    template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
    void CMap<KEY, ARG_KEY, VALUE, ARG_VALUE>::GetNextAssoc(POSITION& rNextPosition,
    KEY& rKey, VALUE& rValue) const
    {
    ASSERT_VALID(this);
    ENSURE(m_pHashTable != NULL);  // never call on empty map CAssoc* pAssocRet = (CAssoc*)rNextPosition;
    ENSURE(pAssocRet != NULL); if (pAssocRet == (CAssoc*) BEFORE_START_POSITION)
    {
    // find the first association
    for (UINT nBucket = 0; nBucket < m_nHashTableSize; nBucket++)
    {
    if ((pAssocRet = m_pHashTable[nBucket]) != NULL)
    {
    break;
    }
    }
    ENSURE(pAssocRet != NULL);  // must find something
    } // find next association
    ASSERT(AfxIsValidAddress(pAssocRet, sizeof(CAssoc)));
    CAssoc* pAssocNext;
    if ((pAssocNext = pAssocRet->pNext) == NULL)
    {
    // go to next bucket
    for (UINT nBucket = (pAssocRet->nHashValue % m_nHashTableSize) + 1;
      nBucket < m_nHashTableSize; nBucket++)
    if ((pAssocNext = m_pHashTable[nBucket]) != NULL)
    break;
    } rNextPosition = (POSITION) pAssocNext; // fill in return data
    rKey = pAssocRet->key;
    rValue = pAssocRet->value;
    }