Revision: 4881
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4881&view=rev
Author:   mdboom
Date:     2008-01-21 10:32:57 -0800 (Mon, 21 Jan 2008)

Log Message:
-----------
Fix memory leak in pcolor and pcolormesh.  (Thanks Rob Hetland)

Modified Paths:
--------------
    trunk/matplotlib/src/_backend_agg.cpp
    trunk/matplotlib/src/_path.cpp

Modified: trunk/matplotlib/src/_backend_agg.cpp
===================================================================
--- trunk/matplotlib/src/_backend_agg.cpp       2008-01-18 18:21:14 UTC (rev 
4880)
+++ trunk/matplotlib/src/_backend_agg.cpp       2008-01-21 18:32:57 UTC (rev 
4881)
@@ -1001,6 +1001,7 @@
 
     for (i = 0; i < N; ++i) {
       typename PathGenerator::path_iterator path = path_generator(i);
+
       if (Ntransforms) {
        trans = transforms[i % Ntransforms];
       } else {
@@ -1070,15 +1071,18 @@
        }
       }
     }
+
+    Py_XDECREF(offsets);
+    Py_XDECREF(facecolors);
+    Py_XDECREF(edgecolors);
+    return Py::Object();
   } catch (...) {
+    printf("Exception!\n");
     Py_XDECREF(offsets);
     Py_XDECREF(facecolors);
     Py_XDECREF(edgecolors);
     throw;
   }
-
-  Py_XDECREF(offsets);
-  return Py::Object();
 }
 
 
@@ -1186,9 +1190,9 @@
 public:
   typedef QuadMeshPathIterator path_iterator;
 
-  inline QuadMeshGenerator(size_t meshWidth, size_t meshHeight, const 
Py::Object& coordinates) :
+  inline QuadMeshGenerator(size_t meshWidth, size_t meshHeight, PyObject* 
coordinates) :
     m_meshWidth(meshWidth), m_meshHeight(meshHeight), m_coordinates(NULL) {
-    PyArrayObject* coordinates_array = 
(PyArrayObject*)PyArray_FromObject(coordinates.ptr(), PyArray_DOUBLE, 3, 3);
+    PyArrayObject* coordinates_array = 
(PyArrayObject*)PyArray_FromObject(coordinates, PyArray_DOUBLE, 3, 3);
     if (!coordinates_array) {
       throw Py::ValueError("Invalid coordinates array.");
     }
@@ -1214,6 +1218,7 @@
   _VERBOSE("RendererAgg::draw_quad_mesh");
   args.verify_length(12);
 
+
   //segments, trans, clipbox, colors, linewidths, antialiaseds
   agg::trans_affine      master_transform = 
py_to_agg_transformation_matrix(args[0]);
   Py::Object             cliprect         = args[1];
@@ -1221,12 +1226,13 @@
   agg::trans_affine       clippath_trans   = 
py_to_agg_transformation_matrix(args[3], false);
   size_t                  mesh_width       = Py::Int(args[4]);
   size_t                  mesh_height      = Py::Int(args[5]);
-  Py::Object              coordinates     = args[6];
+  PyObject*               coordinates     = args[6].ptr();
   Py::Object              offsets_obj      = args[7];
   agg::trans_affine       offset_trans     = 
py_to_agg_transformation_matrix(args[8]);
   Py::Object              facecolors_obj   = args[9];
   bool                    antialiased     = (bool)Py::Int(args[10]);
   bool                    showedges        = (bool)Py::Int(args[11]);
+  bool                    free_edgecolors  = false;
 
   QuadMeshGenerator path_generator(mesh_width, mesh_height, coordinates);
 
@@ -1242,12 +1248,14 @@
     npy_intp dims[] = { 1, 4, 0 };
     double data[] = { 0, 0, 0, 1 };
     edgecolors_obj = PyArray_SimpleNewFromData(2, dims, PyArray_DOUBLE, 
(char*)data);
+    free_edgecolors = true;
   } else {
     if (antialiased) {
       edgecolors_obj = facecolors_obj;
     } else {
       npy_intp dims[] = { 0, 0 };
       edgecolors_obj = PyArray_SimpleNew(1, dims, PyArray_DOUBLE);
+      free_edgecolors = true;
     }
   }
 
@@ -1266,6 +1274,9 @@
      linestyles_obj,
      antialiaseds);
 
+  if (free_edgecolors)
+    Py_XDECREF(edgecolors_obj.ptr());
+
   return Py::Object();
 }
 

Modified: trunk/matplotlib/src/_path.cpp
===================================================================
--- trunk/matplotlib/src/_path.cpp      2008-01-18 18:21:14 UTC (rev 4880)
+++ trunk/matplotlib/src/_path.cpp      2008-01-21 18:32:57 UTC (rev 4881)
@@ -294,11 +294,17 @@
     agg::trans_affine trans = py_to_agg_transformation_matrix(args[1], false);
 
     npy_intp extent_dims[] = { 2, 2, 0 };
-    double* extents_data = new double[4];
+    double* extents_data = NULL;
     double xm, ym;
     PyArrayObject* extents = NULL;
     try
     {
+        extents = (PyArrayObject*)PyArray_SimpleNew
+                  (2, extent_dims, PyArray_DOUBLE);
+        if (extents == NULL)
+            throw Py::MemoryError("Could not allocate result array");
+        extents_data = (double*)PyArray_DATA(extents);
+
         extents_data[0] = std::numeric_limits<double>::infinity();
         extents_data[1] = std::numeric_limits<double>::infinity();
         extents_data[2] = -std::numeric_limits<double>::infinity();
@@ -307,16 +313,10 @@
         ::get_path_extents(path, trans,
                            &extents_data[0], &extents_data[1], 
&extents_data[2], &extents_data[3],
                            &xm, &ym);
-
-        extents = (PyArrayObject*)PyArray_SimpleNewFromData
-                  (2, extent_dims, PyArray_DOUBLE, extents_data);
     }
     catch (...)
     {
-        if (extents)
-            Py_XDECREF(extents);
-        else
-            delete[] extents_data;
+        Py_XDECREF(extents);
         throw;
     }
 
@@ -357,15 +357,27 @@
     Py_XDECREF(input_minpos);
 
     npy_intp extent_dims[] = { 2, 2, 0 };
-    double* extents_data = new double[4];
+    double* extents_data = NULL;
     npy_intp minpos_dims[] = { 2, 0 };
-    double* minpos_data = new double[2];
+    double* minpos_data = NULL;
     PyArrayObject* extents = NULL;
     PyArrayObject* minpos = NULL;
     bool changed = false;
 
     try
     {
+        extents = (PyArrayObject*)PyArray_SimpleNew
+            (2, extent_dims, PyArray_DOUBLE);
+        if (extents == NULL)
+            throw Py::MemoryError("Could not allocate result array");
+        minpos = (PyArrayObject*)PyArray_SimpleNew
+            (1, minpos_dims, PyArray_DOUBLE);
+        if (minpos == NULL)
+            throw Py::MemoryError("Could not allocate result array");
+
+        extents_data = (double*)PyArray_DATA(extents);
+        minpos_data = (double*)PyArray_DATA(minpos);
+
         if (ignore)
         {
             extents_data[0] = std::numeric_limits<double>::infinity();
@@ -396,21 +408,11 @@
                    minpos_data[0]  != xm ||
                    minpos_data[1]  != ym);
 
-        extents = (PyArrayObject*)PyArray_SimpleNewFromData
-                  (2, extent_dims, PyArray_DOUBLE, extents_data);
-        minpos = (PyArrayObject*)PyArray_SimpleNewFromData
-                 (1, minpos_dims, PyArray_DOUBLE, minpos_data);
     }
     catch (...)
     {
-        if (extents)
-            Py_XDECREF(extents);
-        else
-            delete[] extents_data;
-        if (minpos)
-            Py_XDECREF(minpos);
-        else
-            delete[] minpos_data;
+        Py_XDECREF(extents);
+        Py_XDECREF(minpos);
         throw;
     }
 
@@ -419,6 +421,9 @@
     result[1] = Py::Object((PyObject*) minpos);
     result[2] = Py::Int(changed ? 1 : 0);
 
+    Py_XDECREF(extents);
+    Py_XDECREF(minpos);
+
     return result;
 }
 
@@ -964,7 +969,7 @@
 {
     args.verify_length(2);
 
-    Py::Object           bbox   = args[0];
+    Py::Object             bbox   = args[0];
     Py::SeqBase<Py::Object> bboxes = args[1];
 
     double ax0, ay0, ax1, ay1;
@@ -1086,16 +1091,15 @@
     if (polygon.size() == 0)
        return;
     npy_intp polygon_dims[] = { polygon.size() / 2, 2, 0 };
-    double* polygon_data = new double[polygon.size()];
-    memcpy(polygon_data, &polygon[0], polygon.size() * sizeof(double));
     PyArrayObject* polygon_array = NULL;
-    polygon_array = (PyArrayObject*)PyArray_SimpleNewFromData
-       (2, polygon_dims, PyArray_DOUBLE, polygon_data);
+    polygon_array = (PyArrayObject*)PyArray_SimpleNew
+       (2, polygon_dims, PyArray_DOUBLE);
     if (!polygon_array)
     {
-       delete[] polygon_data;
-       throw Py::RuntimeError("Error creating polygon array");
+       throw Py::MemoryError("Error creating polygon array");
     }
+    double* polygon_data = (double*)PyArray_DATA(polygon_array);
+    memcpy(polygon_data, &polygon[0], polygon.size() * sizeof(double));
     polygons.append(Py::Object((PyObject*)polygon_array));
 }
 


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to