fix: 修复 AecDbEwEquipment 的内存泄漏(夹点数组、几何单元、剖切与投影克隆)
This commit is contained in:
1 parent
55391b8dc8
commit
03bbe08b76
2 files changed
+164
-80
No files matched your search
@@ -169,6 +169,19 @@ namespace
|
||||
return pData;
|
||||
}
|
||||
|
||||
//释放一个几何单元。m_pData 在 copyXPrimData、dwgInFieldsForXPrim、byJson
|
||||
//等处一律用 new byte[] / new PVOID[] 分配,必须用 delete[],再删结构体本身
|
||||
void ReleaseXPrimData(AecEqui::XPrimData* pData)
|
||||
{
|
||||
if (pData == NULL) return;
|
||||
if (pData->m_pData != NULL)
|
||||
{
|
||||
delete[](byte*)pData->m_pData;
|
||||
pData->m_pData = NULL;
|
||||
}
|
||||
DELETE_PTR(pData);
|
||||
}
|
||||
|
||||
AecEqui::XPrimData* dwgInFieldsForXPrim(AcDbDwgFiler *pFiler, const Adesk::UInt32 &CurrentVer)
|
||||
{
|
||||
Adesk::Int16 nType = 0;
|
||||
@@ -1521,14 +1534,8 @@ namespace
|
||||
{
|
||||
for (int i = 0; i < arSubPrimPtrs.GetSize(); i++)
|
||||
{
|
||||
AecEqui::XPrimData* pData = (AecEqui::XPrimData*)arSubPrimPtrs.GetAt(i);
|
||||
if (pData != NULL)
|
||||
{
|
||||
if (pData->m_nSize > 0)
|
||||
{
|
||||
delete[](byte*)pData->m_pData;
|
||||
}
|
||||
}
|
||||
//原来只 delete[] m_pData、不删结构体,结构体全部泄漏
|
||||
ReleaseXPrimData((AecEqui::XPrimData*)arSubPrimPtrs.GetAt(i));
|
||||
}
|
||||
arSubPrimPtrs.RemoveAll();
|
||||
}
|
||||
@@ -1687,6 +1694,7 @@ AecDbEwEquipment::~AecDbEwEquipment(void)
|
||||
{
|
||||
Clean3DBuffer();
|
||||
Clean2DBuffer();
|
||||
FreeBuffer(m_arSubPrimPtrs);
|
||||
delete [] m_pGripAppData;
|
||||
}
|
||||
|
||||
@@ -1704,7 +1712,7 @@ Acad::ErrorStatus AecDbEwEquipment::dwgInFields(AcDbDwgFiler* pFiler)
|
||||
}
|
||||
|
||||
//----- Object version number needs to be read first
|
||||
m_pGripAppData = new AecGripData[GRIP_MAXNUM];
|
||||
//夹点数组由构造函数分配,此处不要再分配一次,否则旧数组直接泄漏(约 300KB/实体)
|
||||
Adesk::UInt32 version = 0;
|
||||
if ((es = pFiler->readUInt32(&version)) != Acad::eOk)
|
||||
return (es);
|
||||
@@ -1721,6 +1729,7 @@ Acad::ErrorStatus AecDbEwEquipment::dwgInFields(AcDbDwgFiler* pFiler)
|
||||
if (pszTmp != NULL)
|
||||
{
|
||||
m_sGUID = pszTmp;
|
||||
acutDelString(pszTmp);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -1728,8 +1737,8 @@ Acad::ErrorStatus AecDbEwEquipment::dwgInFields(AcDbDwgFiler* pFiler)
|
||||
Adesk::Int32 nLen = 0;
|
||||
pFiler->readInt32(&nLen);
|
||||
|
||||
//FreeBufer
|
||||
m_arSubPrimPtrs.RemoveAll();
|
||||
//重新读入前先释放旧几何,只 RemoveAll 会漏掉结构体和参数块
|
||||
FreeBuffer(m_arSubPrimPtrs);
|
||||
AecEqui::XPrimData* pSolid = NULL;
|
||||
|
||||
Adesk::Int16 nType = 0;
|
||||
@@ -2848,6 +2857,7 @@ int AecDbEwEquipment::GetDraw2dables(Adesk::UInt16 nDrawStyle, AcDbVoidPtrArray&
|
||||
{
|
||||
//投影法
|
||||
OrthoProjected3DSolid(pSolid,plan,xform,arSubEntPtrs);
|
||||
DELETE_PTR(pClnEnt); //投影函数不接管所有权,原来直接 continue 导致克隆体泄漏
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2855,6 +2865,7 @@ int AecDbEwEquipment::GetDraw2dables(Adesk::UInt16 nDrawStyle, AcDbVoidPtrArray&
|
||||
if (pSubMesh != NULL)
|
||||
{
|
||||
OrthoProjected3DSubMesh(pSubMesh,plan,xform,arSubEntPtrs);
|
||||
DELETE_PTR(pClnEnt);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2962,6 +2973,8 @@ int AecDbEwEquipment::GetDraw3dables(AcDbVoidPtrArray& arEntPtrs,bool bWriteBimI
|
||||
else
|
||||
{
|
||||
pSolidAll->booleanOper(AcDb::kBoolUnite,pSolid);
|
||||
//booleanOper 不接管入参,原来每个被合并掉的克隆体都泄漏
|
||||
DELETE_PTR(pSolid);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -3156,9 +3169,12 @@ void AecDbEwEquipment::subDMesh2NewSolid()
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i(0); i < idxs.size(); ++i)
|
||||
//必须倒序删除:idxs 里存的是删除前的原始下标,正序删会让后面的下标整体前移
|
||||
for (int i((int)idxs.size() - 1); i >= 0; --i)
|
||||
{
|
||||
m_arSubPrimPtrs.RemoveAt(i);
|
||||
int nIndex = idxs[i];
|
||||
ReleaseXPrimData((AecEqui::XPrimData *)m_arSubPrimPtrs[nIndex]);
|
||||
m_arSubPrimPtrs.RemoveAt(nIndex);
|
||||
}
|
||||
|
||||
m_arSubPrimPtrs.Append(ar);
|
||||
@@ -4031,9 +4047,9 @@ bool AecDbEwEquipment::GetClosestPointToSUbPrim(DWORD dwSubiD, AcGePoint3d& ptNe
|
||||
AcArray<AcDbEntity *> regions;
|
||||
pFace->convertToRegion(regions);
|
||||
|
||||
for (int i = 0; i < regions.length(); i++)
|
||||
for (int j = 0; j < regions.length(); j++)
|
||||
{
|
||||
AcDbRegion *pIn = (AcDbRegion *)regions.at(i);
|
||||
AcDbRegion *pIn = (AcDbRegion *)regions.at(j);
|
||||
|
||||
CoreTools::getRegionInfo(pIn, ptC, dA, pln);
|
||||
|
||||
@@ -4045,6 +4061,10 @@ bool AecDbEwEquipment::GetClosestPointToSUbPrim(DWORD dwSubiD, AcGePoint3d& ptNe
|
||||
|
||||
mpPns.insert(std::make_pair(pn.dDis, pn));
|
||||
}
|
||||
|
||||
//convertToRegion 产出的 region 归调用方所有,原来一个都没释放
|
||||
for (int j = 0; j < regions.length(); j++)
|
||||
DELETE_PTR(regions[j]);
|
||||
}
|
||||
delete pEnt;
|
||||
}
|
||||
@@ -4273,7 +4293,7 @@ void AecDbEwEquipment::RemoveSubPrimObj(int nIndex)
|
||||
pSolid = (AecEqui::XPrimData*)m_arSubPrimPtrs.GetAt(nIndex);
|
||||
m_arSubPrimPtrs.RemoveAt(nIndex);
|
||||
m_mapSpecXData.RemoveAt(TypeConvert::i2s(pSolid->m_nID) + _T(":color"));
|
||||
DELETE_PTR(pSolid);
|
||||
ReleaseXPrimData(pSolid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4288,7 +4308,7 @@ void AecDbEwEquipment::RemoveSubPrimObjByID(int nSubID)
|
||||
{
|
||||
m_arSubPrimPtrs.RemoveAt(i);
|
||||
m_mapSpecXData.RemoveAt(TypeConvert::i2s(pSolid->m_nID) + _T(":color"));
|
||||
DELETE_PTR(pSolid);
|
||||
ReleaseXPrimData(pSolid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -11233,7 +11253,11 @@ void AecDbEwEquipment::SortAecComplexCurves(CPtrArray& arPrimCplPtrs) const
|
||||
for (int i = 0; i < arPrimCplPtrs.GetSize(); i++)
|
||||
{
|
||||
AecComplexCurve* pCrv = (AecComplexCurve*)arPrimCplPtrs.GetAt(i);
|
||||
if (pCrv->length() > 0) vtComplexcrv.push_back(pCrv);
|
||||
if (pCrv == NULL) continue;
|
||||
if (pCrv->length() > 0)
|
||||
vtComplexcrv.push_back(pCrv);
|
||||
else
|
||||
DELETE_PTR(pCrv); //空曲线原来被直接丢弃,泄漏
|
||||
}
|
||||
std::sort(vtComplexcrv.begin(), vtComplexcrv.end(), CompareComplexcrvByZ);
|
||||
|
||||
@@ -12556,35 +12580,44 @@ DLLIMPEXP bool MakeBlockRefSet(AcDbVoidPtrArray& arEntPtrs,const AcDbObjectId& i
|
||||
|
||||
AcDbObjectId idRec;
|
||||
AcDbBlockTable *pTbl = NULL;
|
||||
if (Acad::eOk == pDb->getBlockTable(pTbl, AcDb::kForWrite))
|
||||
if (Acad::eOk != pDb->getBlockTable(pTbl, AcDb::kForWrite) || pTbl == NULL)
|
||||
{
|
||||
pTbl->add(idRec, pRec);
|
||||
pTbl->close();
|
||||
|
||||
TCHAR szHd[17];
|
||||
idRec.handle().getIntoAsciiBuffer(szHd);
|
||||
|
||||
if (_tcscmp(pszName, _T("*U")) == 0 ||
|
||||
_tcscmp(pszName, _T("*u")) == 0)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
sName.Format(_T("%s@%s"), pszName, szHd);
|
||||
Acad::ErrorStatus es = pRec->setName(sName);
|
||||
}
|
||||
|
||||
//原来这里直接跳过,pRec 既不关闭也不删除,每次调用泄漏一个块表记录
|
||||
pRec->close();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (idRec.isValid())
|
||||
{
|
||||
AcDbBlockReference *pRef = new AcDbBlockReference;
|
||||
pRef->setBlockTableRecord(idRec);
|
||||
pRef->setRotation(0);
|
||||
pRef->setPosition(ptIns);
|
||||
pRef->setLayer(idLay);
|
||||
arEntPtrs.append(pRef);
|
||||
}
|
||||
Acad::ErrorStatus esAdd = pTbl->add(idRec, pRec);
|
||||
pTbl->close();
|
||||
if (esAdd != Acad::eOk)
|
||||
{
|
||||
pRec->close();
|
||||
return false;
|
||||
}
|
||||
|
||||
TCHAR szHd[17];
|
||||
idRec.handle().getIntoAsciiBuffer(szHd);
|
||||
|
||||
if (_tcscmp(pszName, _T("*U")) == 0 ||
|
||||
_tcscmp(pszName, _T("*u")) == 0)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
sName.Format(_T("%s@%s"), pszName, szHd);
|
||||
Acad::ErrorStatus es = pRec->setName(sName);
|
||||
}
|
||||
|
||||
pRec->close();
|
||||
|
||||
if (idRec.isValid())
|
||||
{
|
||||
AcDbBlockReference *pRef = new AcDbBlockReference;
|
||||
pRef->setBlockTableRecord(idRec);
|
||||
pRef->setRotation(0);
|
||||
pRef->setPosition(ptIns);
|
||||
pRef->setLayer(idLay);
|
||||
arEntPtrs.append(pRef);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -12624,8 +12657,12 @@ bool AecDbEwEquipment::OldGetSectionDraw(AcGePlane &plan, const AcGeVector3d &vt
|
||||
{
|
||||
OrthoProjected3DSolid(pSolidT, plan, xform, arProPtrs);
|
||||
}
|
||||
//非 solid 的克隆体原来既不进结果也不释放
|
||||
DELETE_PTR(pSubCln);
|
||||
}
|
||||
}
|
||||
//GetDraw3dables 产出的整组克隆,原来从头到尾没释放
|
||||
FreeBuffer(arSubPtrs);
|
||||
|
||||
CString sName;
|
||||
m_mapSpecXData.GetAt(KEY_NAME, sName);
|
||||
@@ -12688,6 +12725,7 @@ bool AecDbEwEquipment::GetSectionDraw(AcGePlane& plan,const AcGeVector3d& vtTo,A
|
||||
//不是2个接口,走投影,不画符号
|
||||
if (pFit->GetInterfaceCount() != 2)
|
||||
{
|
||||
delete pFit; //原来直接 return,克隆出来的整份设备泄漏
|
||||
return OldGetSectionDraw(plan, vtTo, arRegionPtrs);
|
||||
}
|
||||
|
||||
@@ -12739,6 +12777,7 @@ bool AecDbEwEquipment::GetSectionDraw(AcGePlane& plan,const AcGeVector3d& vtTo,A
|
||||
}
|
||||
else//不是阀门,其他设备
|
||||
{
|
||||
delete pFit;
|
||||
return OldGetSectionDraw(plan, vtTo, arRegionPtrs);
|
||||
}
|
||||
}
|
||||
@@ -12848,11 +12887,17 @@ bool AecDbEwEquipment::ByJson(const SHJson::WValue &v)
|
||||
it = v.FindMember(_T("__arSubPrimPtrs__"));
|
||||
if (it == v.MemberEnd()) return false;
|
||||
if (!it->value.IsArray()) return false;
|
||||
|
||||
//先释放旧几何,否则对已有对象再导入会叠加重复单元
|
||||
FreeBuffer(m_arSubPrimPtrs);
|
||||
|
||||
for (VCIt i = it->value.Begin(); i != it->value.End(); ++i)
|
||||
{
|
||||
AecEqui::XPrimData *p = new AecEqui::XPrimData;
|
||||
if (byJson(*i, p))
|
||||
m_arSubPrimPtrs.Add(p);
|
||||
else
|
||||
ReleaseXPrimData(p); //解析失败,原来既不进数组也不释放
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
Reference in new issue
Block a user