Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 07cc2c9

Browse files
committed
Fix memory leak in pcolor and pcolormesh. (Thanks Rob Hetland)
svn path=/trunk/matplotlib/; revision=4881
1 parent d87eb4e commit 07cc2c9

2 files changed

Lines changed: 50 additions & 35 deletions

File tree

src/_backend_agg.cpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,7 @@ RendererAgg::_draw_path_collection_generic
10011001

10021002
for (i = 0; i < N; ++i) {
10031003
typename PathGenerator::path_iterator path = path_generator(i);
1004+
10041005
if (Ntransforms) {
10051006
trans = transforms[i % Ntransforms];
10061007
} else {
@@ -1070,15 +1071,18 @@ RendererAgg::_draw_path_collection_generic
10701071
}
10711072
}
10721073
}
1074+
1075+
Py_XDECREF(offsets);
1076+
Py_XDECREF(facecolors);
1077+
Py_XDECREF(edgecolors);
1078+
return Py::Object();
10731079
} catch (...) {
1080+
printf("Exception!\n");
10741081
Py_XDECREF(offsets);
10751082
Py_XDECREF(facecolors);
10761083
Py_XDECREF(edgecolors);
10771084
throw;
10781085
}
1079-
1080-
Py_XDECREF(offsets);
1081-
return Py::Object();
10821086
}
10831087

10841088

@@ -1186,9 +1190,9 @@ class QuadMeshGenerator {
11861190
public:
11871191
typedef QuadMeshPathIterator path_iterator;
11881192

1189-
inline QuadMeshGenerator(size_t meshWidth, size_t meshHeight, const Py::Object& coordinates) :
1193+
inline QuadMeshGenerator(size_t meshWidth, size_t meshHeight, PyObject* coordinates) :
11901194
m_meshWidth(meshWidth), m_meshHeight(meshHeight), m_coordinates(NULL) {
1191-
PyArrayObject* coordinates_array = (PyArrayObject*)PyArray_FromObject(coordinates.ptr(), PyArray_DOUBLE, 3, 3);
1195+
PyArrayObject* coordinates_array = (PyArrayObject*)PyArray_FromObject(coordinates, PyArray_DOUBLE, 3, 3);
11921196
if (!coordinates_array) {
11931197
throw Py::ValueError("Invalid coordinates array.");
11941198
}
@@ -1214,19 +1218,21 @@ RendererAgg::draw_quad_mesh(const Py::Tuple& args) {
12141218
_VERBOSE("RendererAgg::draw_quad_mesh");
12151219
args.verify_length(12);
12161220

1221+
12171222
//segments, trans, clipbox, colors, linewidths, antialiaseds
12181223
agg::trans_affine master_transform = py_to_agg_transformation_matrix(args[0]);
12191224
Py::Object cliprect = args[1];
12201225
Py::Object clippath = args[2];
12211226
agg::trans_affine clippath_trans = py_to_agg_transformation_matrix(args[3], false);
12221227
size_t mesh_width = Py::Int(args[4]);
12231228
size_t mesh_height = Py::Int(args[5]);
1224-
Py::Object coordinates = args[6];
1229+
PyObject* coordinates = args[6].ptr();
12251230
Py::Object offsets_obj = args[7];
12261231
agg::trans_affine offset_trans = py_to_agg_transformation_matrix(args[8]);
12271232
Py::Object facecolors_obj = args[9];
12281233
bool antialiased = (bool)Py::Int(args[10]);
12291234
bool showedges = (bool)Py::Int(args[11]);
1235+
bool free_edgecolors = false;
12301236

12311237
QuadMeshGenerator path_generator(mesh_width, mesh_height, coordinates);
12321238

@@ -1242,12 +1248,14 @@ RendererAgg::draw_quad_mesh(const Py::Tuple& args) {
12421248
npy_intp dims[] = { 1, 4, 0 };
12431249
double data[] = { 0, 0, 0, 1 };
12441250
edgecolors_obj = PyArray_SimpleNewFromData(2, dims, PyArray_DOUBLE, (char*)data);
1251+
free_edgecolors = true;
12451252
} else {
12461253
if (antialiased) {
12471254
edgecolors_obj = facecolors_obj;
12481255
} else {
12491256
npy_intp dims[] = { 0, 0 };
12501257
edgecolors_obj = PyArray_SimpleNew(1, dims, PyArray_DOUBLE);
1258+
free_edgecolors = true;
12511259
}
12521260
}
12531261

@@ -1266,6 +1274,9 @@ RendererAgg::draw_quad_mesh(const Py::Tuple& args) {
12661274
linestyles_obj,
12671275
antialiaseds);
12681276

1277+
if (free_edgecolors)
1278+
Py_XDECREF(edgecolors_obj.ptr());
1279+
12691280
return Py::Object();
12701281
}
12711282

src/_path.cpp

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -294,11 +294,17 @@ Py::Object _path_module::get_path_extents(const Py::Tuple& args)
294294
agg::trans_affine trans = py_to_agg_transformation_matrix(args[1], false);
295295

296296
npy_intp extent_dims[] = { 2, 2, 0 };
297-
double* extents_data = new double[4];
297+
double* extents_data = NULL;
298298
double xm, ym;
299299
PyArrayObject* extents = NULL;
300300
try
301301
{
302+
extents = (PyArrayObject*)PyArray_SimpleNew
303+
(2, extent_dims, PyArray_DOUBLE);
304+
if (extents == NULL)
305+
throw Py::MemoryError("Could not allocate result array");
306+
extents_data = (double*)PyArray_DATA(extents);
307+
302308
extents_data[0] = std::numeric_limits<double>::infinity();
303309
extents_data[1] = std::numeric_limits<double>::infinity();
304310
extents_data[2] = -std::numeric_limits<double>::infinity();
@@ -307,16 +313,10 @@ Py::Object _path_module::get_path_extents(const Py::Tuple& args)
307313
::get_path_extents(path, trans,
308314
&extents_data[0], &extents_data[1], &extents_data[2], &extents_data[3],
309315
&xm, &ym);
310-
311-
extents = (PyArrayObject*)PyArray_SimpleNewFromData
312-
(2, extent_dims, PyArray_DOUBLE, extents_data);
313316
}
314317
catch (...)
315318
{
316-
if (extents)
317-
Py_XDECREF(extents);
318-
else
319-
delete[] extents_data;
319+
Py_XDECREF(extents);
320320
throw;
321321
}
322322

@@ -357,15 +357,27 @@ Py::Object _path_module::update_path_extents(const Py::Tuple& args)
357357
Py_XDECREF(input_minpos);
358358

359359
npy_intp extent_dims[] = { 2, 2, 0 };
360-
double* extents_data = new double[4];
360+
double* extents_data = NULL;
361361
npy_intp minpos_dims[] = { 2, 0 };
362-
double* minpos_data = new double[2];
362+
double* minpos_data = NULL;
363363
PyArrayObject* extents = NULL;
364364
PyArrayObject* minpos = NULL;
365365
bool changed = false;
366366

367367
try
368368
{
369+
extents = (PyArrayObject*)PyArray_SimpleNew
370+
(2, extent_dims, PyArray_DOUBLE);
371+
if (extents == NULL)
372+
throw Py::MemoryError("Could not allocate result array");
373+
minpos = (PyArrayObject*)PyArray_SimpleNew
374+
(1, minpos_dims, PyArray_DOUBLE);
375+
if (minpos == NULL)
376+
throw Py::MemoryError("Could not allocate result array");
377+
378+
extents_data = (double*)PyArray_DATA(extents);
379+
minpos_data = (double*)PyArray_DATA(minpos);
380+
369381
if (ignore)
370382
{
371383
extents_data[0] = std::numeric_limits<double>::infinity();
@@ -396,21 +408,11 @@ Py::Object _path_module::update_path_extents(const Py::Tuple& args)
396408
minpos_data[0] != xm ||
397409
minpos_data[1] != ym);
398410

399-
extents = (PyArrayObject*)PyArray_SimpleNewFromData
400-
(2, extent_dims, PyArray_DOUBLE, extents_data);
401-
minpos = (PyArrayObject*)PyArray_SimpleNewFromData
402-
(1, minpos_dims, PyArray_DOUBLE, minpos_data);
403411
}
404412
catch (...)
405413
{
406-
if (extents)
407-
Py_XDECREF(extents);
408-
else
409-
delete[] extents_data;
410-
if (minpos)
411-
Py_XDECREF(minpos);
412-
else
413-
delete[] minpos_data;
414+
Py_XDECREF(extents);
415+
Py_XDECREF(minpos);
414416
throw;
415417
}
416418

@@ -419,6 +421,9 @@ Py::Object _path_module::update_path_extents(const Py::Tuple& args)
419421
result[1] = Py::Object((PyObject*) minpos);
420422
result[2] = Py::Int(changed ? 1 : 0);
421423

424+
Py_XDECREF(extents);
425+
Py_XDECREF(minpos);
426+
422427
return result;
423428
}
424429

@@ -964,7 +969,7 @@ Py::Object _path_module::count_bboxes_overlapping_bbox(const Py::Tuple& args)
964969
{
965970
args.verify_length(2);
966971

967-
Py::Object bbox = args[0];
972+
Py::Object bbox = args[0];
968973
Py::SeqBase<Py::Object> bboxes = args[1];
969974

970975
double ax0, ay0, ax1, ay1;
@@ -1086,16 +1091,15 @@ void _add_polygon(Py::List& polygons, const std::vector<double>& polygon) {
10861091
if (polygon.size() == 0)
10871092
return;
10881093
npy_intp polygon_dims[] = { polygon.size() / 2, 2, 0 };
1089-
double* polygon_data = new double[polygon.size()];
1090-
memcpy(polygon_data, &polygon[0], polygon.size() * sizeof(double));
10911094
PyArrayObject* polygon_array = NULL;
1092-
polygon_array = (PyArrayObject*)PyArray_SimpleNewFromData
1093-
(2, polygon_dims, PyArray_DOUBLE, polygon_data);
1095+
polygon_array = (PyArrayObject*)PyArray_SimpleNew
1096+
(2, polygon_dims, PyArray_DOUBLE);
10941097
if (!polygon_array)
10951098
{
1096-
delete[] polygon_data;
1097-
throw Py::RuntimeError("Error creating polygon array");
1099+
throw Py::MemoryError("Error creating polygon array");
10981100
}
1101+
double* polygon_data = (double*)PyArray_DATA(polygon_array);
1102+
memcpy(polygon_data, &polygon[0], polygon.size() * sizeof(double));
10991103
polygons.append(Py::Object((PyObject*)polygon_array));
11001104
}
11011105

0 commit comments

Comments
 (0)