<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Generator" CONTENT="MS Exchange Server version 6.5.7651.59">
<TITLE>Proposed fix for #169 - memory leak</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/plain format -->

<P><FONT SIZE=2>Hi all -<BR>
<BR>
I'm relatively new to GEOS, and decided to poke around at some of the outstanding issues to get better acquainted.&nbsp; I started with the memory leak from <A HREF="http://trac.osgeo.org/geos/ticket/169">http://trac.osgeo.org/geos/ticket/169</A><BR>
<BR>
Here's what was causing the leak:<BR>
-&nbsp; GEOSisValid calls IsValidOp::isValid() and IsValidOp::getValidationError().<BR>
-&nbsp; Both of these methods call IsValidOp::checkValid(const Geometry *g)<BR>
-&nbsp; The first time IsValidOp::checkValid is called, isChecked is false and validErr is NULL. An error is found, a new TopologyValidationError object is created and assigned to validErr, but isChecked is still false.<BR>
- Subsequent calls to IsValidOp::checkValid, isChecked is still false, validErr is assigned NULL, losing the previous TopologyValidationError object. A new TVE object is later allocated and assigned to validErr, isChecked is still false.<BR>
<BR>
The fix:<BR>
- at the end of IsValidOp::checkValid(const Geometry *g), set isChecked to true. validErr is either still NULL (if no error was found) or it may point to a TVE object.<BR>
<BR>
I did not originally download the svn trunk version, so I can't create a proper patch, but here is my diff from the geos-3.0.0 version that I downloaded in Sept.&nbsp; The change is on line 129.<BR>
<BR>
[denise@localhost valid]$ diff -C5 IsValidOp.cpp.orig IsValidOp.cpp<BR>
*** IsValidOp.cpp.orig&nbsp; 2008-10-22 14:02:31.000000000 -0400<BR>
--- IsValidOp.cpp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2008-10-23 09:54:46.000000000 -0400<BR>
***************<BR>
*** 124,133 ****<BR>
--- 124,134 ----<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (typeid(*g)==typeid(Polygon)) checkValid((Polygon*)g);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (typeid(*g)==typeid(MultiPolygon)) checkValid((MultiPolygon*)g);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if ((gc=dynamic_cast&lt;const GeometryCollection *&gt;(g)))<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; checkValid(gc);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else throw util::UnsupportedOperationException();<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isChecked=true;<BR>
&nbsp; }<BR>
<BR>
&nbsp; /*<BR>
&nbsp;&nbsp; * Checks validity of a Point.<BR>
&nbsp;&nbsp; */<BR>
<BR>
<BR>
Thanks,<BR>
Denise</FONT>
</P>

</BODY>
</HTML>