我写了一个解析CTreeCtrl树路径的方法,里面需要多次调用GetItemText方法,当我调用三四千次的时候没问题,但是调用六七千次以上时,程序就报错,不懂为什么。我把我的代码贴出来。
我是循环调用这个方法的,每次将树的一个节点传进来。
//获得叶节点全路径
CString CDlgInstInit::GetFullPath(HTREEITEM hItem,UINT nFlag)
{
CString strTemp="",strLD="";
HTREEITEM hParent=hItem;
while(hParent)
{
strTemp = m_wndTree.GetItemText( hParent ) + strTemp;  //在这个地方程序就出错
strTemp = CString(".") + strTemp ;
hParent = m_wndTree.GetParentItem(hParent);
}
if(nFlag==1)
strTemp=strTemp+"1";
strTemp=strTemp.Mid(1);
HTREEITEM hTemp=m_wndTree.GetRootItem();
CUnitBase *pDataUnit = (CUnitBase*) m_wndTree.GetItemData(hTemp); 
strLD=pDataUnit->m_pParentUnit->GetChildrenUnitByName("inst")->GetText();
strTemp=strLD+"/"+strTemp;
return strTemp;
}

解决方案 »

  1.   

    可能strTemp 这个变量出了问题.
      

  2.   

    不是,是在m_wndTree.GetItemText( hParent )这里出错的,我把这句放到strTemp 赋值之前了,调试显示是在m_wndTree.GetItemText( hParent )那里出错。
      

  3.   

    弹出错误提示:0xC0000005:Access Violation
      

  4.   

    有可能是别的地方引起的,导致 m_wndTree无效了
      

  5.   


    那正好说明是别的地方出现这样的问题,导致现在m_wndTree无效典型的情况是内存越界
      

  6.   

    m_wndTree->GetItemText( hParent );查堆栈错误在这里发生。
    First-chance exception in TEST.exe (NTDLL.DLL): 0xC00000FD: Stack Overflow
      

  7.   

    有可能是你调用GetFullPath的CDlgInstInit对象指针非法,或者对象窗口已经关闭
    这导致hParent = m_wndTree.GetParentItem(hParent); 总是返回非空值,程序死循环耗尽stack检查一下调用的地方
      

  8.   

    Stack Overflow通常是局部(动态)变量/数组定义太多了,把大数组和较大的类对象改成用new分配,函数返回前delete。
      

  9.   

    一个消极的处理方法
    只能避免程序异常,但是不能根本解决错误问题
    CString CDlgInstInit::GetFullPath(HTREEITEM hItem,UINT nFlag) 

        CString strTemp="",strLD="";
        if(!::IsWindow(m_wndTree.m_hWnd))
            return _T("");HTREEITEM hParent=hItem; 
    while(hParent) 
    ...
      

  10.   

    int GetPathColl(HTREEITEM hITEM)
    {
    if(hITEM==NULL)
    return 0; if(m_wndTree.ItemHasChildren(hITEM)) //如果有子节点,继续递归
    {
    CUnitBase *pDataUnit = (CUnitBase*) m_wndTree.GetItemData(hITEM); 
    pUnitColl.push_back(pDataUnit);
    pathColl.push_back( GetFullPath(hITEM,0) );
    hITEM=m_wndTree.GetChildItem(hITEM);  
    GetPathColl(hITEM);              
            }
    else if(m_wndTree.GetNextSiblingItem( hITEM )) //如果有兄弟节点,继续递归
    {
    CUnitBase *pDataUnit = (CUnitBase*) m_wndTree.GetItemData(hITEM); 
    pUnitColl.push_back(pDataUnit);
    pathColl.push_back( GetFullPath(hITEM,1) );                             //GetFullPath出错前的堆栈在这里 hITEM=m_wndTree.GetNextSiblingItem( hITEM );
    GetPathColl(hITEM);
    }
    else //为叶子节点
    {
    CUnitBase *pDataUnit = (CUnitBase*) m_wndTree.GetItemData(hITEM); 
    pUnitColl.push_back(pDataUnit);
    pathColl.push_back( GetFullPath(hITEM,1) );
    hITEM=m_wndTree.GetParentItem(hITEM);
    while(hITEM)
    {
    if(m_wndTree.GetNextSiblingItem( hITEM ))
    {
    hITEM=m_wndTree.GetNextSiblingItem( hITEM );
    break;
    }
    else
    hITEM=m_wndTree.GetParentItem(hITEM);
    }
      if(hITEM==m_wndTree.GetRootItem())
    return 0;
    else
    GetPathColl(hITEM);
    }
    count = pathColl.size();
    return count;
    }问题还没解决,到底问题在哪里啊,同志们帮忙啊。
    我把调用函数的代码也贴出来,高手再帮忙看看看,谢谢了!
      

  11.   

    int GetPathColl(HTREEITEM hITEM)
    {
    if(hITEM==NULL)
    return 0; if(m_wndTree.ItemHasChildren(hITEM)) //如果有子节点,继续递归
    {
    CUnitBase *pDataUnit = (CUnitBase*) m_wndTree.GetItemData(hITEM); 
    pUnitColl.push_back(pDataUnit);
    pathColl.push_back( GetFullPath(hITEM,0) );
    hITEM=m_wndTree.GetChildItem(hITEM);  
    GetPathColl(hITEM);              
            }
    else if(m_wndTree.GetNextSiblingItem( hITEM )) //如果有兄弟节点,继续递归
    {
    CUnitBase *pDataUnit = (CUnitBase*) m_wndTree.GetItemData(hITEM); 
    pUnitColl.push_back(pDataUnit);
    pathColl.push_back( GetFullPath(hITEM,1) );                             //GetFullPath出错前的堆栈在这里 hITEM=m_wndTree.GetNextSiblingItem( hITEM );
    GetPathColl(hITEM);
    }
    else //为叶子节点
    {
    CUnitBase *pDataUnit = (CUnitBase*) m_wndTree.GetItemData(hITEM); 
    pUnitColl.push_back(pDataUnit);
    pathColl.push_back( GetFullPath(hITEM,1) );
    hITEM=m_wndTree.GetParentItem(hITEM);
    while(hITEM)
    {
    if(m_wndTree.GetNextSiblingItem( hITEM ))
    {
    hITEM=m_wndTree.GetNextSiblingItem( hITEM );
    break;
    }
    else
    hITEM=m_wndTree.GetParentItem(hITEM);
    }
      if(hITEM==m_wndTree.GetRootItem())
    return 0;
    else
    GetPathColl(hITEM);
    }
    count = pathColl.size();
    return count;
    }问题还没解决,到底问题在哪里啊,同志们帮忙啊。
    我把调用函数的代码也贴出来,高手再帮忙看看看,谢谢了!
      

  12.   

    pathColl.push_back( GetFullPath(hITEM,1) ); 这句调用了GetFullPath之后就在GetFullPath函数里m_wndTree->GetItemText( hParent )出现错误,First-chance exception in TEST.exe (NTDLL.DLL): 0xC00000FD: Stack Overflow
      

  13.   

    循环,递归设计不当会产生 stack overflow,改称非递归算法
      

  14.   

    是算法问题,网上找了个算法,就没有出现堆栈溢出的问题。
    结贴给分了。
    int GetPathColl(HTREEITEM hITEM) 

           HTREEITEM hrNext = NULL;
          HTREEITEM hrChild = NULL;      if(hITEM == NULL)
               return 0;
      
          CUnitBase *pDataUnit = (CUnitBase*) m_wndTree.GetItemData(hITEM); 
      pUnitColl.push_back(pDataUnit);
      if(m_wndTree.ItemHasChildren(hITEM))
      pathColl.push_back( GetFullPath(hITEM,0) );
      else
      pathColl.push_back( GetFullPath(hITEM,1) );      hrChild = m_wndTree.GetChildItem(hITEM);
          GetPathColl(hrChild);//遍历子节点      hrNext=m_wndTree.GetNextItem(hITEM,TVGN_NEXT);
          GetPathColl(hrNext);//遍历兄弟节点
    count = pathColl.size();
    return count;
    }
      

  15.   

    CString strTemp,CString 中所放的字符内容是有限制的,到五六千次的时候已经超过这个容量了。要清空。