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