From: <md...@us...> - 2008-01-21 18:33:59
|
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. |