Fixed some memory leaks when using polygonal component for faces. Deallocations more stable and clear for each component, using also local dynamic memory deallocs. Changed Clear() method of TriMesh which guarantees perfect deallocations of faces' components. Fixed also CompactFaceVector which now deallocates faces before resizing the vector. In DeleteFace, not only the flag is set, but also the face's components are deallocated.

This commit is contained in:
giorgiomarcias 2014-12-15 15:36:37 +00:00
parent ac56acdd9f
commit 882d54d6ae
3 changed files with 105 additions and 84 deletions

View File

@ -646,6 +646,7 @@ public:
{ {
assert(&f >= &m.face.front() && &f <= &m.face.back()); assert(&f >= &m.face.front() && &f <= &m.face.back());
assert(!f.IsD()); assert(!f.IsD());
f.Dealloc();
f.SetD(); f.SetD();
--m.fn; --m.fn;
} }
@ -970,6 +971,8 @@ public:
// Loop on the faces to correct VF and FF relations // Loop on the faces to correct VF and FF relations
pu.oldBase = &m.face[0]; pu.oldBase = &m.face[0];
pu.oldEnd = &m.face.back()+1; pu.oldEnd = &m.face.back()+1;
for(size_t i=m.fn;i<m.face.size();++i)
m.face[i].Dealloc();
m.face.resize(m.fn); m.face.resize(m.fn);
pu.newBase = (m.face.empty())?0:&m.face[0]; pu.newBase = (m.face.empty())?0:&m.face[0];
pu.newEnd = (m.face.empty())?0:&m.face.back()+1; pu.newEnd = (m.face.empty())?0:&m.face.back()+1;

View File

@ -324,24 +324,13 @@ public:
/// Default constructor /// Default constructor
TriMesh() TriMesh()
{ {
Clear(); Clear();
} }
/// destructor /// destructor
~TriMesh() ~TriMesh()
{ {
typename std::set< PointerToAttribute>::iterator i; Clear();
for( i = vert_attr.begin(); i != vert_attr.end(); ++i)
delete ((SimpleTempDataBase*)(*i)._handle);
for( i = edge_attr.begin(); i != edge_attr.end(); ++i)
delete ((SimpleTempDataBase*)(*i)._handle);
for( i = face_attr.begin(); i != face_attr.end(); ++i)
delete ((SimpleTempDataBase*)(*i)._handle);
for( i = mesh_attr.begin(); i != mesh_attr.end(); ++i)
delete ((SimpleTempDataBase*)(*i)._handle);
FaceIterator fi;
for(fi = face.begin(); fi != face.end(); ++fi) (*fi).Dealloc();
} }
int Mem(const int & nv, const int & nf) const { int Mem(const int & nv, const int & nf) const {
@ -365,38 +354,50 @@ public:
/// Function to destroy the mesh /// Function to destroy the mesh
void Clear() void Clear()
{ {
typename std::set< PointerToAttribute>::iterator i;
for( i = vert_attr.begin(); i != vert_attr.end(); ++i)
delete ((SimpleTempDataBase*)(*i)._handle);
for( i = edge_attr.begin(); i != edge_attr.end(); ++i)
delete ((SimpleTempDataBase*)(*i)._handle);
for( i = face_attr.begin(); i != face_attr.end(); ++i)
delete ((SimpleTempDataBase*)(*i)._handle);
for( i = mesh_attr.begin(); i != mesh_attr.end(); ++i)
delete ((SimpleTempDataBase*)(*i)._handle);
for(FaceIterator fi = face.begin(); fi != face.end(); ++fi)
(*fi).Dealloc();
vert.clear(); vert.clear();
face.clear(); face.clear();
edge.clear(); edge.clear();
// textures.clear(); // textures.clear();
// normalmaps.clear(); // normalmaps.clear();
vn = 0; vn = 0;
en = 0; en = 0;
fn = 0; fn = 0;
hn = 0; hn = 0;
imark = 0; imark = 0;
attrn = 0; attrn = 0;
C()=Color4b::Gray; C()=Color4b::Gray;
} }
bool IsEmpty() const bool IsEmpty() const
{ {
return vert.empty() && edge.empty() && face.empty(); return vert.empty() && edge.empty() && face.empty();
} }
int & SimplexNumber(){ return fn;} int & SimplexNumber(){ return fn;}
int & VertexNumber(){ return vn;} int & VertexNumber(){ return vn;}
/// The incremental mark /// The incremental mark
int imark; int imark;
private: private:
// TriMesh cannot be copied. Use Append (see vcg/complex/append.h) // TriMesh cannot be copied. Use Append (see vcg/complex/append.h)
TriMesh operator =(const TriMesh & /*m*/){assert(0);return TriMesh();} TriMesh operator =(const TriMesh & /*m*/){assert(0);return TriMesh();}
TriMesh(const TriMesh & ){} TriMesh(const TriMesh & ){}
}; // end class Mesh }; // end class Mesh

View File

@ -37,16 +37,18 @@ protected:
} }
public: public:
PolyInfo(){ _ns = -1; } PolyInfo(){ _ns = -1; }
/* Note: the destructor will not be called in general because there are no virtual destructors.
Instead, the job of deallocating the memory will be done by the face allocator.
This destructor is only done for those who istance a face alone (outside a mesh)
*/
static bool HasPolyInfo() { return true; } static bool HasPolyInfo() { return true; }
inline const int & VN() const { return _ns;} inline const int & VN() const { return _ns;}
inline int Prev(const int & i){ return (i+(VN()-1))%VN();} inline int Prev(const int & i){ return (i+(VN()-1))%VN();}
inline int Next(const int & i){ return (i+1)%VN();} inline int Next(const int & i){ return (i+1)%VN();}
inline void Alloc(const int & /*ns*/){} inline void Alloc(const int & ns){
inline void Dealloc(){} T::Alloc(ns);
__SetVN(ns);
}
inline void Dealloc(){
T::Dealloc();
__SetVN(-1);
}
private: private:
int _ns; int _ns;
@ -58,7 +60,13 @@ public:
typedef typename T::VertexType::ScalarType ScalarType; typedef typename T::VertexType::ScalarType ScalarType;
typedef typename T::VertexType VertexType; typedef typename T::VertexType VertexType;
PFVAdj(){_vpoly = NULL;} PFVAdj(){ _vpoly = NULL; }
/* Note: the destructor will not be called in general because there are no virtual destructors.
* Instead, the job of deallocating the memory will be done by the face allocator.
* This destructor is only done for those who istance a face alone (outside a mesh)
*/
// ~PFVAdj(){ __Dealloc(); }
inline typename T::VertexType * & V( const int j ) { assert(j>=0 && j<this->VN()); return _vpoly[j]; } inline typename T::VertexType * & V( const int j ) { assert(j>=0 && j<this->VN()); return _vpoly[j]; }
inline typename T::VertexType * const & V( const int j ) const { assert(j>=0 && j<this->VN()); return _vpoly[j]; } inline typename T::VertexType * const & V( const int j ) const { assert(j>=0 && j<this->VN()); return _vpoly[j]; }
inline typename T::VertexType * cV( const int j ) const { assert(j>=0 && j<this->VN()); return _vpoly[j]; } inline typename T::VertexType * cV( const int j ) const { assert(j>=0 && j<this->VN()); return _vpoly[j]; }
@ -90,37 +98,37 @@ public:
template <class LeftF> template <class LeftF>
void ImportData(const LeftF & leftF){ T::ImportData(leftF);} void ImportData(const LeftF & leftF){ T::ImportData(leftF);}
inline void Alloc(const int & ns) { inline void Alloc(const int & ns) {
if(_vpoly == NULL){ __Dealloc();
this->__SetVN(ns); _vpoly = new typename T::VertexType*[ns];
_vpoly = new typename T::VertexType*[this->VN()]; for(int i = 0; i < ns; ++i) _vpoly[i] = 0;
for(int i = 0; i < this->VN(); ++i) _vpoly[i] = 0;
}
T::Alloc(ns); T::Alloc(ns);
} }
inline void Dealloc() { inline void Dealloc() {
if(_vpoly!=NULL){ __Dealloc();
delete [] _vpoly;
_vpoly = NULL;
this->__SetVN(-1);
}
T::Dealloc(); T::Dealloc();
} }
static bool HasFVAdjacency() { return true; } static bool HasFVAdjacency() { return true; }
static void Name(std::vector<std::string> & name){name.push_back(std::string("PFVAdj"));T::Name(name);} static void Name(std::vector<std::string> & name){name.push_back(std::string("PFVAdj"));T::Name(name);}
private: private:
inline void __Dealloc(){
delete [] _vpoly;
_vpoly = NULL;
}
typename T::VertexPointer *_vpoly; typename T::VertexPointer *_vpoly;
}; };
template <class T> class PVFAdj: public T { template <class T> class PVFAdj: public T {
public: public:
PVFAdj(){_vfiP = NULL; _vfiP = NULL;} PVFAdj(){ _vfiP = NULL; _vfiP = NULL; }
/* Note: the destructor will not be called in general because there are no virtual destructors. /* Note: the destructor will not be called in general because there are no virtual destructors.
Instead, the job of deallocating the memory will be done bu the edge allocator. * Instead, the job of deallocating the memory will be done by the face allocator.
This destructor is only done for those who istance a face alone (outside a mesh) * This destructor is only done for those who istance a face alone (outside a mesh)
*/ */
// ~PVFAdj(){ __Dealloc(); }
typedef typename T::VertexType VertexType; typedef typename T::VertexType VertexType;
typedef typename T::FaceType FaceType; typedef typename T::FaceType FaceType;
typename T::FacePointer &VFp(const int j) { assert(j>=0 && j<this->VN()); return _vfpP[j]; } typename T::FacePointer &VFp(const int j) { assert(j>=0 && j<this->VN()); return _vfpP[j]; }
@ -130,22 +138,14 @@ public:
template <class LeftF> template <class LeftF>
void ImportData(const LeftF & leftF){T::ImportData(leftF);} void ImportData(const LeftF & leftF){T::ImportData(leftF);}
inline void Alloc(const int & ns) { inline void Alloc(const int & ns) {
if(_vfpP == NULL){ _vfpP = new FaceType*[ns];
this->__SetVN(ns); _vfiP = new char[ns];
_vfpP = new FaceType*[this->VN()]; for(int i = 0; i < ns; ++i) {_vfpP[i] = 0;_vfiP[i] = -1;}
_vfiP = new char[this->VN()];
for(int i = 0; i < this->VN(); ++i) {_vfpP[i] = 0;_vfiP[i] = -1;}
}
T::Alloc(ns); T::Alloc(ns);
} }
unsigned int SizeNeigh(){ return this->VN();} unsigned int SizeNeigh(){ return this->VN();}
inline void Dealloc() { inline void Dealloc() {
if(_vfpP!=NULL){ __Dealloc();
delete [] _vfpP; _vfpP = NULL;
delete [] _vfiP; _vfiP = NULL;
}
T::Dealloc(); T::Dealloc();
} }
@ -153,6 +153,11 @@ public:
static void Name(std::vector<std::string> & name){name.push_back(std::string("PVFAdj"));T::Name(name);} static void Name(std::vector<std::string> & name){name.push_back(std::string("PVFAdj"));T::Name(name);}
private: private:
inline void __Dealloc(){
delete [] _vfpP; _vfpP = NULL;
delete [] _vfiP; _vfiP = NULL;
}
typename T::FacePointer *_vfpP ; typename T::FacePointer *_vfpP ;
char *_vfiP ; char *_vfiP ;
}; };
@ -162,7 +167,12 @@ private:
template <class T> class PFFAdj: public T { template <class T> class PFFAdj: public T {
public: public:
typedef typename T::FaceType FaceType; typedef typename T::FaceType FaceType;
PFFAdj(){_ffpP = NULL; _ffiP = NULL; } PFFAdj(){ _ffpP = NULL; _ffiP = NULL; }
/* Note: the destructor will not be called in general because there are no virtual destructors.
* Instead, the job of deallocating the memory will be done by the face allocator.
* This destructor is only done for those who istance a face alone (outside a mesh)
*/
// ~PFFAdj(){ __Dealloc(); }
typename T::FacePointer &FFp(const int j) { assert(j>=0 && j<this->VN()); return _ffpP[j]; } typename T::FacePointer &FFp(const int j) { assert(j>=0 && j<this->VN()); return _ffpP[j]; }
typename T::FacePointer FFp(const int j) const { assert(j>=0 && j<this->VN()); return _ffpP[j]; } typename T::FacePointer FFp(const int j) const { assert(j>=0 && j<this->VN()); return _ffpP[j]; }
typename T::FacePointer cFFp(const int j) const { assert(j>=0 && j<this->VN()); return _ffpP[j]; } typename T::FacePointer cFFp(const int j) const { assert(j>=0 && j<this->VN()); return _ffpP[j]; }
@ -172,19 +182,13 @@ public:
template <class LeftF> template <class LeftF>
void ImportData(const LeftF & leftF){T::ImportData(leftF);} void ImportData(const LeftF & leftF){T::ImportData(leftF);}
inline void Alloc(const int & ns) { inline void Alloc(const int & ns) {
if( _ffpP == NULL){ _ffpP = new FaceType*[ns];
this->__SetVN(ns); _ffiP = new char[ns];
_ffpP = new FaceType*[this->VN()]; for(int i = 0; i < ns; ++i) {_ffpP[i] = 0;_ffiP[i] = 0;}
_ffiP = new char[this->VN()];
for(int i = 0; i < this->VN(); ++i) {_ffpP[i] = 0;_ffiP[i] = 0;}
}
T::Alloc(ns); T::Alloc(ns);
} }
inline void Dealloc() { inline void Dealloc() {
if(_ffpP!=NULL){ __Dealloc();
delete [] _ffpP; _ffpP = NULL;
delete [] _ffiP; _ffiP = NULL;
}
T::Dealloc(); T::Dealloc();
} }
@ -192,6 +196,11 @@ public:
static void Name(std::vector<std::string> & name){name.push_back(std::string("PFFAdj"));T::Name(name);} static void Name(std::vector<std::string> & name){name.push_back(std::string("PFFAdj"));T::Name(name);}
private: private:
inline void __Dealloc(){
delete [] _ffpP; _ffpP = NULL;
delete [] _ffiP; _ffiP = NULL;
}
typename T::FacePointer *_ffpP ; typename T::FacePointer *_ffpP ;
char *_ffiP ; char *_ffiP ;
}; };
@ -201,7 +210,12 @@ private:
template <class T> class PFEAdj: public T { template <class T> class PFEAdj: public T {
public: public:
typedef typename T::EdgeType EdgeType; typedef typename T::EdgeType EdgeType;
PFEAdj(){_fepP = NULL; } PFEAdj(){ _fepP = NULL; }
/* Note: the destructor will not be called in general because there are no virtual destructors.
* Instead, the job of deallocating the memory will be done by the face allocator.
* This destructor is only done for those who istance a face alone (outside a mesh)
*/
// ~PFEAdj(){ __Dealloc(); }
typename T::EdgePointer &FEp(const int j) { assert(j>=0 && j<this->VN()); return _fepP[j]; } typename T::EdgePointer &FEp(const int j) { assert(j>=0 && j<this->VN()); return _fepP[j]; }
typename T::EdgePointer const FEp(const int j) const { assert(j>=0 && j<this->VN()); return _fepP[j]; } typename T::EdgePointer const FEp(const int j) const { assert(j>=0 && j<this->VN()); return _fepP[j]; }
typename T::EdgePointer const cFEp(const int j) const { assert(j>=0 && j<this->VN()); return _fepP[j]; } typename T::EdgePointer const cFEp(const int j) const { assert(j>=0 && j<this->VN()); return _fepP[j]; }
@ -209,19 +223,22 @@ public:
template <class LeftF> template <class LeftF>
void ImportData(const LeftF & leftF){T::ImportData(leftF);} void ImportData(const LeftF & leftF){T::ImportData(leftF);}
inline void Alloc(const int & ns) { inline void Alloc(const int & ns) {
if( _fepP == NULL){ _fepP = new EdgeType *[ns];
this->__SetVN(ns); for(int i = 0; i < ns; ++i) {_fepP[i] = 0;}
_fepP = new EdgeType *[this->VN()];
for(int i = 0; i < this->VN(); ++i) {_fepP[i] = 0;}
}
T::Alloc(ns); T::Alloc(ns);
} }
inline void Dealloc() { if(_fepP!=NULL) {delete [] _fepP; _fepP = NULL;} T::Dealloc();} inline void Dealloc() {
T::Dealloc();
}
static bool HasFEAdjacency() { return true; } static bool HasFEAdjacency() { return true; }
static void Name(std::vector<std::string> & name){name.push_back(std::string("PFEAdj"));T::Name(name);} static void Name(std::vector<std::string> & name){name.push_back(std::string("PFEAdj"));T::Name(name);}
private: private:
inline void __Dealloc(){
delete [] _fepP; _fepP = NULL;
}
typename T::EdgePointer *_fepP ; typename T::EdgePointer *_fepP ;
}; };
@ -233,7 +250,7 @@ public:
typedef typename T::HEdgeType HEdgeType; typedef typename T::HEdgeType HEdgeType;
typedef typename T::HEdgePointer HEdgePointer; typedef typename T::HEdgePointer HEdgePointer;
PFHAdj(){_fhP = NULL; } PFHAdj(){ _fhP = NULL; }
typename T::HEdgePointer &FHp() { return _fhP; } typename T::HEdgePointer &FHp() { return _fhP; }
typename T::HEdgePointer const cFHp() const { return _fhP; } typename T::HEdgePointer const cFHp() const { return _fhP; }