From Sebastien Messerschmidt, "attached you'll find a patch for the shp-plugin.

I've spotted huge memory leaks int ShapeParser and fixed them.
Also, there was a missing destructor (PolygonM) and a missing member initialization (PolygonZ)
Would be nice if someone could test the changes.

To release the memory just if no reading error happened (and therefore the arrays would be valid) I've added an macro to release and reset the pointers at once. I'm not using macros myself very often as I don't like them, but I think it doesn't hurt in this code.

"
This commit is contained in:
Robert Osfield 2008-05-08 15:17:53 +00:00
parent dc0355fc84
commit ebf3804c84
2 changed files with 61 additions and 10 deletions

View File

@ -10,6 +10,8 @@
using namespace ESRIShape ; using namespace ESRIShape ;
#define SAFE_DELETE_ARRAY( ptr ) delete[] ptr; ptr = 0L;
template <class T> template <class T>
inline void swapBytes( T &s ) inline void swapBytes( T &s )
{ {
@ -243,7 +245,7 @@ MultiPoint::MultiPoint( const struct MultiPoint &mpoint ): ShapeObject(ShapeType
MultiPoint::~MultiPoint() MultiPoint::~MultiPoint()
{ {
delete [] points; delete[] points;
} }
bool MultiPoint::read( int fd ) bool MultiPoint::read( int fd )
@ -251,6 +253,8 @@ bool MultiPoint::read( int fd )
RecordHeader rh; RecordHeader rh;
if( rh.read(fd) == false ) if( rh.read(fd) == false )
return false; return false;
SAFE_DELETE_ARRAY( points );
Integer shapeType; Integer shapeType;
if( readVal<Integer>(fd, shapeType, LittleEndian ) == false ) if( readVal<Integer>(fd, shapeType, LittleEndian ) == false )
@ -317,6 +321,9 @@ bool PolyLine::read( int fd )
if( rh.read(fd) == false ) if( rh.read(fd) == false )
return false; return false;
SAFE_DELETE_ARRAY( parts );
SAFE_DELETE_ARRAY( points );
Integer shapeType; Integer shapeType;
if( readVal<Integer>(fd, shapeType, LittleEndian ) == false ) if( readVal<Integer>(fd, shapeType, LittleEndian ) == false )
return false; return false;
@ -386,6 +393,9 @@ bool Polygon::read( int fd )
if( rh.read(fd) == false ) if( rh.read(fd) == false )
return false; return false;
SAFE_DELETE_ARRAY( parts );
SAFE_DELETE_ARRAY( points );
Integer shapeType; Integer shapeType;
if( readVal<Integer>(fd, shapeType, LittleEndian ) == false ) if( readVal<Integer>(fd, shapeType, LittleEndian ) == false )
return false; return false;
@ -501,6 +511,9 @@ bool MultiPointM::read( int fd )
if( rh.read(fd) == false ) if( rh.read(fd) == false )
return false; return false;
SAFE_DELETE_ARRAY( points );
SAFE_DELETE_ARRAY( mArray );
Integer shapeType; Integer shapeType;
if( readVal<Integer>(fd, shapeType, LittleEndian ) == false ) if( readVal<Integer>(fd, shapeType, LittleEndian ) == false )
return false; return false;
@ -590,6 +603,10 @@ bool PolyLineM::read( int fd )
if( rh.read(fd) == false ) if( rh.read(fd) == false )
return false; return false;
SAFE_DELETE_ARRAY( parts );
SAFE_DELETE_ARRAY( points );
SAFE_DELETE_ARRAY( mArray );
Integer shapeType; Integer shapeType;
if( readVal<Integer>(fd, shapeType, LittleEndian ) == false ) if( readVal<Integer>(fd, shapeType, LittleEndian ) == false )
return false; return false;
@ -670,12 +687,24 @@ PolygonM::PolygonM(const PolygonM &p):
} }
} }
PolygonM::~PolygonM()
{
delete[] parts;
delete[] points;
delete[] mArray;
};
bool PolygonM::read( int fd ) bool PolygonM::read( int fd )
{ {
RecordHeader rh; RecordHeader rh;
if( rh.read(fd) == false ) if( rh.read(fd) == false )
return false; return false;
SAFE_DELETE_ARRAY( parts );
SAFE_DELETE_ARRAY( points );
SAFE_DELETE_ARRAY( mArray );
Integer shapeType; Integer shapeType;
if( readVal<Integer>(fd, shapeType, LittleEndian ) == false ) if( readVal<Integer>(fd, shapeType, LittleEndian ) == false )
return false; return false;
@ -820,6 +849,10 @@ bool MultiPointZ::read( int fd )
if( rh.read(fd) == false ) if( rh.read(fd) == false )
return false; return false;
SAFE_DELETE_ARRAY( points );
SAFE_DELETE_ARRAY( zArray );
SAFE_DELETE_ARRAY( mArray );
Integer shapeType; Integer shapeType;
if( readVal<Integer>(fd, shapeType, LittleEndian ) == false ) if( readVal<Integer>(fd, shapeType, LittleEndian ) == false )
return false; return false;
@ -923,8 +956,7 @@ PolyLineZ::~PolyLineZ()
delete [] parts; delete [] parts;
delete [] points; delete [] points;
delete [] zArray; delete [] zArray;
if( mArray != 0L ) delete [] mArray;
delete [] mArray;
} }
bool PolyLineZ::read( int fd ) bool PolyLineZ::read( int fd )
@ -933,6 +965,11 @@ bool PolyLineZ::read( int fd )
if( rh.read(fd) == false ) if( rh.read(fd) == false )
return false; return false;
SAFE_DELETE_ARRAY( parts );
SAFE_DELETE_ARRAY( points );
SAFE_DELETE_ARRAY( zArray );
SAFE_DELETE_ARRAY( mArray );
Integer shapeType; Integer shapeType;
if( readVal<Integer>(fd, shapeType, LittleEndian ) == false ) if( readVal<Integer>(fd, shapeType, LittleEndian ) == false )
return false; return false;
@ -976,7 +1013,7 @@ bool PolyLineZ::read( int fd )
int Y = X + (15 * numPoints); int Y = X + (15 * numPoints);
int Z = Y + 16 + (8 * numPoints); int Z = Y + 16 + (8 * numPoints);
if( rh.contentLength > Z ) if( rh.contentLength != Z )
{ {
mRange.read(fd); mRange.read(fd);
mArray = new Double[numPoints]; mArray = new Double[numPoints];
@ -996,7 +1033,8 @@ PolygonZ::PolygonZ():
numParts(0), numParts(0),
numPoints(0), numPoints(0),
parts(0L), parts(0L),
points(0L) , points(0L),
zArray(0L),
mArray(0L) mArray(0L)
{} {}
@ -1020,6 +1058,8 @@ PolygonZ::PolygonZ(const PolygonZ &p):
{ {
points[i] = p.points[i]; points[i] = p.points[i];
zArray[i] = p.zArray[i]; // jcm zArray[i] = p.zArray[i]; // jcm
// M-Array seems to be missing sometimes
if(p.mArray)
mArray[i] = p.mArray[i]; mArray[i] = p.mArray[i];
} }
} }
@ -1029,8 +1069,7 @@ PolygonZ::~PolygonZ()
delete [] parts; delete [] parts;
delete [] points; delete [] points;
delete [] zArray; delete [] zArray;
if( mArray != 0L ) delete [] mArray;
delete [] mArray;
} }
bool PolygonZ::read( int fd ) bool PolygonZ::read( int fd )
@ -1038,6 +1077,11 @@ bool PolygonZ::read( int fd )
RecordHeader rh; RecordHeader rh;
if( rh.read(fd) == false ) if( rh.read(fd) == false )
return false; return false;
SAFE_DELETE_ARRAY( parts );
SAFE_DELETE_ARRAY( points );
SAFE_DELETE_ARRAY( zArray );
SAFE_DELETE_ARRAY( mArray );
Integer shapeType; Integer shapeType;
if( readVal<Integer>(fd, shapeType, LittleEndian ) == false ) if( readVal<Integer>(fd, shapeType, LittleEndian ) == false )
@ -1082,7 +1126,7 @@ bool PolygonZ::read( int fd )
int X = 44 + (4*numParts); int X = 44 + (4*numParts);
int Y = X + (16*numPoints); int Y = X + (16*numPoints);
int Z = Y + 16 + (8*numPoints); int Z = Y + 16 + (8*numPoints);
if( rh.contentLength > Z ) if( rh.contentLength != Z )
{ {
if( mRange.read(fd) == false ) if( mRange.read(fd) == false )
return false; return false;
@ -1165,8 +1209,7 @@ MultiPatch::~MultiPatch()
delete [] partTypes; delete [] partTypes;
delete [] points; delete [] points;
delete [] zArray; delete [] zArray;
if( mArray != 0L ) delete [] mArray;
delete [] mArray;
} }
bool MultiPatch::read( int fd ) bool MultiPatch::read( int fd )
@ -1175,6 +1218,12 @@ bool MultiPatch::read( int fd )
if( rh.read(fd) == false ) if( rh.read(fd) == false )
return false; return false;
SAFE_DELETE_ARRAY( parts );
SAFE_DELETE_ARRAY( partTypes );
SAFE_DELETE_ARRAY( points );
SAFE_DELETE_ARRAY( zArray );
SAFE_DELETE_ARRAY( mArray );
Integer shapeType; Integer shapeType;
if( readVal<Integer>(fd, shapeType, LittleEndian ) == false ) if( readVal<Integer>(fd, shapeType, LittleEndian ) == false )
return false; return false;

View File

@ -274,6 +274,8 @@ struct PolygonM : public ShapeObject
PolygonM(const PolygonM &p); PolygonM(const PolygonM &p);
virtual ~PolygonM();
bool read( int fd ); bool read( int fd );
}; };