如题,小弟在使用CImageList类时遇到了一个非常奇怪的现象开始我声明CVarListView如下:
class CVarListView : public CListView
{
..............................//此处省略了其它成员函数和变量protected:
int LISTNUM;
CImageList m_listIcon;
};
发生Debug错误,错误情况如下,在程序结束时发生异常
void CView::PostNcDestroy()
{
// default for views is to allocate them on the heap
//  the default post-cleanup is to 'delete this'.
//  never explicitly call 'delete' on a view
delete this;  //此时发生错误,但是this不为空
}如果随便天上一变量i,在执行一遍则无调试错误
class CVarListView : public CListView
{
..............................//此处省略了其它成员函数和变量protected:
int LISTNUM;
int i;
CImageList m_listIcon;
}注:此类中使用m_listIcon的地方
void CVarListView::OnInitialUpdate() 
{
CListView::OnInitialUpdate(); m_listIcon.Create(IDR_VAR_ICON_LIST, 16, 0, RGB(255,255,255));
GetListCtrl().SetImageList( &m_listIcon, LVSIL_SMALL);

GetListCtrl().SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES); ShowListHead();
RefreshVarList();
}
添加列表项时代码如下:
Item.mask = LVIF_TEXT|LVIF_IMAGE;
Item.iItem = nItem;
Item.iSubItem = 0;
Item.pszText = VarNameText.GetBuffer(0);
Item.iImage = it->GetType();//此值为一图标ID(从0开始)
GetListCtrl().InsertItem(&Item);问题虽然没有了,小弟极度困惑。望各位大虾指点,小弟先敬礼了!!!!!!!!!!!!!!!!!!!

解决方案 »

  1.   

    问题应该还在,如果你release的话,可能会崩溃的
      

  2.   

    如果屏蔽SetImageList会不会有错?如果没有,可能是ImageList和ListView的重复注销造成的,你可以在ListView的窗体注销前将它的ImageList句柄设置为空试试
      

  3.   

    应该是CImageList的m_listIcon被其它的成员变量溢出攻击了,请查看其它的变量定义是否有buffer溢出
      

  4.   

    多谢各位大虾帮忙,上边的方法都试过了 还是不行上边错误描述不太清楚,最终出错的地方是这个函数:
    void __cdecl _free_dbg_lk(#else  /* _MT */_CRTIMP void __cdecl _free_dbg(#endif  /* _MT */        void * pUserData,
            int nBlockUse
            )
    {
            _CrtMemBlockHeader * pHead;        /* verify heap before freeing */
            if (_crtDbgFlag & _CRTDBG_CHECK_ALWAYS_DF)
                _ASSERTE(_CrtCheckMemory());        if (pUserData == NULL)
                return;        /* forced failure */
            if (!(*_pfnAllocHook)(_HOOK_FREE, pUserData, 0, nBlockUse, 0L, NULL, 0))
            {
                _RPT0(_CRT_WARN, "Client hook free failure.\n");            return;
            }        /*
             * If this ASSERT fails, a bad pointer has been passed in. It may be
             * totally bogus, or it may have been allocated from another heap.
             * The pointer MUST come from the 'local' heap.
             */
            _ASSERTE(_CrtIsValidHeapPointer(pUserData));        /* get a pointer to memory block header */
            pHead = pHdr(pUserData);        /* verify block type */
            _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));        /* if we didn't already check entire heap, at least check this object */
            if (!(_crtDbgFlag & _CRTDBG_CHECK_ALWAYS_DF))
            {
                /* check no-mans-land gaps */
                if (!CheckBytes(pHead->gap, _bNoMansLandFill, nNoMansLandSize))
                    _RPT3(_CRT_ERROR, "DAMAGE: before %hs block (#%d) at 0x%08X.\n",
                        szBlockUseName[_BLOCK_TYPE(pHead->nBlockUse)],
                        pHead->lRequest,
                        (BYTE *) pbData(pHead));            if (!CheckBytes(pbData(pHead) + pHead->nDataSize, _bNoMansLandFill, nNoMansLandSize))
                    _RPT3(_CRT_ERROR, "DAMAGE: after %hs block (#%d) at 0x%08X.\n",
                        szBlockUseName[_BLOCK_TYPE(pHead->nBlockUse)],
                        pHead->lRequest,
                        (BYTE *) pbData(pHead)); //调试器停在这一行,不知为何???
                                                   指针都有值,但是不能查看指向的内容
            }        if (pHead->nBlockUse == _IGNORE_BLOCK)
            {
                _ASSERTE(pHead->nLine == IGNORE_LINE && pHead->lRequest == IGNORE_REQ);
                /* fill the entire block including header with dead-land-fill */
                memset(pHead, _bDeadLandFill,
                    sizeof(_CrtMemBlockHeader) + pHead->nDataSize + nNoMansLandSize);
                _free_base(pHead);
                return;
            }        /* CRT blocks can be freed as NORMAL blocks */
            if (pHead->nBlockUse == _CRT_BLOCK && nBlockUse == _NORMAL_BLOCK)
                nBlockUse = _CRT_BLOCK;        /* Error if freeing incorrect memory type */
            _ASSERTE(pHead->nBlockUse == nBlockUse);        /* keep track of total amount of memory allocated */
            _lCurAlloc -= pHead->nDataSize;        /* optionally reclaim memory */
            if (!(_crtDbgFlag & _CRTDBG_DELAY_FREE_MEM_DF))
            {
                /* remove from the linked list */
                if (pHead->pBlockHeaderNext)
                {
                    pHead->pBlockHeaderNext->pBlockHeaderPrev = pHead->pBlockHeaderPrev;
                }
                else
                {
                    _ASSERTE(_pLastBlock == pHead);
                    _pLastBlock = pHead->pBlockHeaderPrev;
                }            if (pHead->pBlockHeaderPrev)
                {
                    pHead->pBlockHeaderPrev->pBlockHeaderNext = pHead->pBlockHeaderNext;
                }
                else
                {
                    _ASSERTE(_pFirstBlock == pHead);
                    _pFirstBlock = pHead->pBlockHeaderNext;
                }            /* fill the entire block including header with dead-land-fill */
                memset(pHead, _bDeadLandFill,
                    sizeof(_CrtMemBlockHeader) + pHead->nDataSize + nNoMansLandSize);
                _free_base(pHead);
            }
            else
            {
                pHead->nBlockUse = _FREE_BLOCK;            /* keep memory around as dead space */
                memset(pbData(pHead), _bDeadLandFill, pHead->nDataSize);
            }
    }修改之后成了如下定义
    {
    ...............
    protected:
    CImageList m_listIcon;
    };出现错误,而且现在必须在前边添加两个int内存长度的变量才可以避免调试错误
      

  5.   

    类的全部定义如下:
    class CVarListView : public CListView
    {
    protected:
    CVarListView();           // protected constructor used by dynamic creationpublic:
    enum { LIST_NUMBER = 9};
    // Attributes
    public:
    //ÏÔʾ±äÁ¿ÐÅÏ¢Ïà¹Ø
    void ShowVarsInfor(CVarManager *pShowList);   //ÏòÁбí¿Ø¼þ³õʼ»¯ÐÅÏ¢
    void ShowListHead(void);              //ÏÔʾ±äÁ¿ÁбíÍ·
    void RefreshVarList(void); //ÉèÖñíÍ·ÖÐÿ¸ö±äÁ¿ÊôÐԵĿí¶È
    void SetAllColumnWidth(void); //±äÁ¿²Ù×÷Ïà¹Ø
    BOOL DeleteVar(CString &varName);  //ɾ³ý
    BOOL EditVar(CString &varName);  //±à¼­
    BOOL AddVar(CString *pVarName);  //Ìí¼Ó£¬Èç¹û´«ÈëµÄ±äÁ¿Ãû³Æ²»¿Õ£¬Ìí¼ÓÔڴ˱äÁ¿Ö®ºó£¬·ñÔò¼ÓÔÚ½áβprotected:
    //»ñµÃ´¦ÓÚÑ¡ÖÐ״̬µÄ±äÁ¿Ãû³Æ
    CString GetSelectVarName(void); //·µ»ØÑ¡ÖеÄÁеÄË÷Òý£¨ÒÔ0¿ªÊ¼£©£¬Èç¹û·µ»ØֵСÓÚ0±íÃ÷δѡÖÐ
    int GetSelectIndex(void) { return GetListCtrl().GetSelectionMark(); } 
    // Operations
    public:
    //Òª¸²¸ÇµÄ´¿Ð麯Êý
    virtual CLib::CPOUMap* GetPOUTypeList(BOOL bAll,int nPouType,CLib::CPOUMap &POUList)=0;
    virtual BOOL IsCanEdit(void)=0;
    virtual CVarManager* GetPOUVarList(void)=0;
    virtual int GetVarListType(void)=0;
    // Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CVarListView)
    public:
    virtual void OnInitialUpdate();
    protected:
    virtual void OnDraw(CDC* pDC);      // overridden to draw this view
    virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);
    //}}AFX_VIRTUAL// Implementation
    protected:
    virtual ~CVarListView();
    #ifdef _DEBUG
    virtual void AssertValid() const;
    virtual void Dump(CDumpContext& dc) const;
    #endif // Generated message map functions
    protected:
    //{{AFX_MSG(CVarListView)
    afx_msg void OnTimer(UINT nIDEvent);
    afx_msg void OnDblclk(NMHDR* pNMHDR, LRESULT* pResult);
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
    afx_msg void OnVarAdd();
    afx_msg void OnVarDelete();
    afx_msg void OnVarUpdate();
    afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnUpdateVarAdd(CCmdUI* pCmdUI);
    afx_msg void OnUpdateVarDelete(CCmdUI* pCmdUI);
    afx_msg void OnUpdateVarUpdate(CCmdUI* pCmdUI);
    afx_msg void OnSize(UINT nType, int cx, int cy);
    //}}AFX_MSGprotected:
    int j;
    int i;
    CImageList m_listIcon;
    };
      

  6.   

    呵呵,问题已经解决。原来代码没有错,ReBuild一次就OK了。
    还是我们项目经理解决的,真是高手!!他说可能是和VC的编译机制有关,采用增量编译的方式,具体怎么回事就不知道了。也许就是一个Bug。