各位,我在一个类的析构函数中写下下面的代码,请问是什么问题,使程序老是出现错误。

时间:2022-05-10 23:27:29
CRgnImage *pRgnImag;

if(NULL == pRgnList) return;

while(!pRgnList->IsEmpty())
{
pRgnImag = pRgnList->GetTail();
delete pRgnImag->pImage;
delete pRgnList->GetTail();
pRgnImag = NULL;
pRgnList->RemoveTail();
}
delete pRgnList;

error:
Debug assert failed!
file:dbgheap.c
line:1017
Expression _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

终止  重试   忽略

12 个解决方案

#1



change:

delete pRgnList->GetTail();

to:

delete pRgnImag;

#2


没有完整程序,
所以只有估计一下:

delete pRgnImag->pImage;
delete pRgnList->GetTail();

delete了两次pImage所指向的内存区域

#3


delete pRgnImag->pImage之前最好先判断,
pRgnImag->pImage是否为NULL,如果为NULL,不需要delete,
而且delete 的时候出现的这种最经常的可能是因为delete 
数组的时候而你用直接用delete pRgnImag->pImage,
比如改成 delete[] pRgnImag->pImage看看!试试!

#4


delete pRgnList->GetTail();

笔误? 

只能建议多检查一下各个指针。

#5


另外,按ALT+F7,可以看看出错的时候的栈的情况。当然exception的时候要选retry。
可能是废话。

#6


pRgnList定义为
CList<CRgnIamge*, CRgnImage*> pRgnList

#7


首先多谢各位帮忙,上面的各种方法都尝试过了,结果仍然一样,跟踪发现,pRgnList含有两个或两个以上的元素时,才出此问题,而且,总是在循环的第二次出现该问题。再请各位帮助!

#8


首先多谢各位帮忙,上面的各种方法都尝试过了,结果仍然一样,跟踪发现,pRgnList含有两个或两个以上的元素时,才出此问题,而且,总是在循环的第二次出现该问题。再请各位帮助!
另外,

pRgnImag定义为对象指针 CRgnImage *pRgnImag
pImage也定义为对象指针 CImageProc *pImage,它是类的成员。

#9


我觉得你第一要保证在删除之前,先保证该指针的有效性,如果指向的已经是被删除的,再删除的时候就会出现非法操作,这点可以在每次delete后赋null值做为保证。另外我对你这里提出一点建议,pImage是CRgnImage 中的成员指针,应该由该类去析构掉。不可以在这里delete pRgnImag->pImage类似的操作。在
delete pRgnList->GetTail();
加上
CRgnImage *pRgnImag=(CRgnImage *)pRgnList->GetTail();
看其指针是否有效!希望对你又帮助!

    

    

#10


我不是VC程序员,不过我认为可能是由于下面这一句的原因
pRgnList->RemoveTail();
把这句屏蔽看看

#11


代码修改如下:
CRightDownView::~CRightDownView()
{
CRgnImage *pRgnImag;

if(NULL == pRgnList) return;

while(!pRgnList->IsEmpty())
{
//CRgnImage *pRgnImag;
pRgnImag = pRgnList->GetTail();

//if(pRgnImag != NULL)
// delete pRgnImag->pImage;
delete pRgnImag;
//pRgnImag = NULL;
//delete pRgnList->GetTail();
pRgnList->RemoveTail();
}
delete pRgnList;
}
跟踪发现:
第一次循环:pRgnList = 0x014c2190  pRgnImage = 0x014c2610
第二次循环:pRgnList = 0x014c2190  pRgnImage = 0x014c1660
并在第二次循环的 delete pRgnImag;时出错!
我怀疑是不是因为CList<> 的问题。我是先
pRgnList = new CList<...>,
然后将pRgnList->AddHead(pRgnImage);

#12


CList的两个函数如下,我在程序中只需要pRgnList->RemoveTail() 是否就行了呢?我不敢肯定,请各位帮帮忙看看!

template<class TYPE, class ARG_TYPE>
TYPE CList<TYPE, ARG_TYPE>::RemoveTail()
{
ASSERT_VALID(this);
ASSERT(m_pNodeTail != NULL);  // don't call on empty list !!!
ASSERT(AfxIsValidAddress(m_pNodeTail, sizeof(CNode)));

CNode* pOldNode = m_pNodeTail;
TYPE returnValue = pOldNode->data;

m_pNodeTail = pOldNode->pPrev;
if (m_pNodeTail != NULL)
m_pNodeTail->pNext = NULL;
else
m_pNodeHead = NULL;
FreeNode(pOldNode);
return returnValue;
}

template<class TYPE, class ARG_TYPE>
void CList<TYPE, ARG_TYPE>::FreeNode(CList::CNode* pNode)
{
DestructElements<TYPE>(&pNode->data, 1);
pNode->pNext = m_pNodeFree;
m_pNodeFree = pNode;
m_nCount--;
ASSERT(m_nCount >= 0);  // make sure we don't underflow

// if no more elements, cleanup completely
if (m_nCount == 0)
RemoveAll();
}

#1



change:

delete pRgnList->GetTail();

to:

delete pRgnImag;

#2


没有完整程序,
所以只有估计一下:

delete pRgnImag->pImage;
delete pRgnList->GetTail();

delete了两次pImage所指向的内存区域

#3


delete pRgnImag->pImage之前最好先判断,
pRgnImag->pImage是否为NULL,如果为NULL,不需要delete,
而且delete 的时候出现的这种最经常的可能是因为delete 
数组的时候而你用直接用delete pRgnImag->pImage,
比如改成 delete[] pRgnImag->pImage看看!试试!

#4


delete pRgnList->GetTail();

笔误? 

只能建议多检查一下各个指针。

#5


另外,按ALT+F7,可以看看出错的时候的栈的情况。当然exception的时候要选retry。
可能是废话。

#6


pRgnList定义为
CList<CRgnIamge*, CRgnImage*> pRgnList

#7


首先多谢各位帮忙,上面的各种方法都尝试过了,结果仍然一样,跟踪发现,pRgnList含有两个或两个以上的元素时,才出此问题,而且,总是在循环的第二次出现该问题。再请各位帮助!

#8


首先多谢各位帮忙,上面的各种方法都尝试过了,结果仍然一样,跟踪发现,pRgnList含有两个或两个以上的元素时,才出此问题,而且,总是在循环的第二次出现该问题。再请各位帮助!
另外,

pRgnImag定义为对象指针 CRgnImage *pRgnImag
pImage也定义为对象指针 CImageProc *pImage,它是类的成员。

#9


我觉得你第一要保证在删除之前,先保证该指针的有效性,如果指向的已经是被删除的,再删除的时候就会出现非法操作,这点可以在每次delete后赋null值做为保证。另外我对你这里提出一点建议,pImage是CRgnImage 中的成员指针,应该由该类去析构掉。不可以在这里delete pRgnImag->pImage类似的操作。在
delete pRgnList->GetTail();
加上
CRgnImage *pRgnImag=(CRgnImage *)pRgnList->GetTail();
看其指针是否有效!希望对你又帮助!

    

    

#10


我不是VC程序员,不过我认为可能是由于下面这一句的原因
pRgnList->RemoveTail();
把这句屏蔽看看

#11


代码修改如下:
CRightDownView::~CRightDownView()
{
CRgnImage *pRgnImag;

if(NULL == pRgnList) return;

while(!pRgnList->IsEmpty())
{
//CRgnImage *pRgnImag;
pRgnImag = pRgnList->GetTail();

//if(pRgnImag != NULL)
// delete pRgnImag->pImage;
delete pRgnImag;
//pRgnImag = NULL;
//delete pRgnList->GetTail();
pRgnList->RemoveTail();
}
delete pRgnList;
}
跟踪发现:
第一次循环:pRgnList = 0x014c2190  pRgnImage = 0x014c2610
第二次循环:pRgnList = 0x014c2190  pRgnImage = 0x014c1660
并在第二次循环的 delete pRgnImag;时出错!
我怀疑是不是因为CList<> 的问题。我是先
pRgnList = new CList<...>,
然后将pRgnList->AddHead(pRgnImage);

#12


CList的两个函数如下,我在程序中只需要pRgnList->RemoveTail() 是否就行了呢?我不敢肯定,请各位帮帮忙看看!

template<class TYPE, class ARG_TYPE>
TYPE CList<TYPE, ARG_TYPE>::RemoveTail()
{
ASSERT_VALID(this);
ASSERT(m_pNodeTail != NULL);  // don't call on empty list !!!
ASSERT(AfxIsValidAddress(m_pNodeTail, sizeof(CNode)));

CNode* pOldNode = m_pNodeTail;
TYPE returnValue = pOldNode->data;

m_pNodeTail = pOldNode->pPrev;
if (m_pNodeTail != NULL)
m_pNodeTail->pNext = NULL;
else
m_pNodeHead = NULL;
FreeNode(pOldNode);
return returnValue;
}

template<class TYPE, class ARG_TYPE>
void CList<TYPE, ARG_TYPE>::FreeNode(CList::CNode* pNode)
{
DestructElements<TYPE>(&pNode->data, 1);
pNode->pNext = m_pNodeFree;
m_pNodeFree = pNode;
m_nCount--;
ASSERT(m_nCount >= 0);  // make sure we don't underflow

// if no more elements, cleanup completely
if (m_nCount == 0)
RemoveAll();
}