From 59d911d345f7a87b30d9061143e973f41400ba5e Mon Sep 17 00:00:00 2001 From: =?utf8?q?St=C3=A9phane=20MOTTELET?= Date: Fri, 21 Jun 2019 12:11:17 +0200 Subject: [PATCH] * Bug 15248: lsq() was leaking memory http://bugzilla.scilab.org/show_bug.cgi?id=15248 Change-Id: I6b1358f7f1509f70e89598782628fcff32922c45 --- scilab/CHANGES.md | 1 + .../linear_algebra/sci_gateway/cpp/sci_lsq.cpp | 30 ++++++++++++++++---- .../tests/nonreg_tests/bug_15248.tst | 27 ++++++++++++++++++ 3 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 scilab/modules/linear_algebra/tests/nonreg_tests/bug_15248.tst diff --git a/scilab/CHANGES.md b/scilab/CHANGES.md index 1814ebd..a908e35 100644 --- a/scilab/CHANGES.md +++ b/scilab/CHANGES.md @@ -153,6 +153,7 @@ Bug Fixes * [#15321](http://bugzilla.scilab.org/show_bug.cgi?id=15321): `lu()` was leaking memory. * [#15425](http://bugzilla.scilab.org/show_bug.cgi?id=15425): The Kronecker product `a.*.b` failed when `a` or `b` or both are hypermatrices, with one or both being polynomials or rationals. * [#15523](http://bugzilla.scilab.org/show_bug.cgi?id=15523): `%ODEOPTIONS(1)=2` didn't work with solvers 'rk' and 'rkf' +* [#15248](http://bugzilla.scilab.org/show_bug.cgi?id=15248): `lsq()`was leaking memory. * [#15577](http://bugzilla.scilab.org/show_bug.cgi?id=15577): `edit` did not accept a line number as text, as with `edit linspace 21`. * [#15668](http://bugzilla.scilab.org/show_bug.cgi?id=15668): `save(filename)` saved all predefined Scilab constants %e %pi etc.. (regression) * [#15812](http://bugzilla.scilab.org/show_bug.cgi?id=15812): On assigning variables the source variable may become become corrupted diff --git a/scilab/modules/linear_algebra/sci_gateway/cpp/sci_lsq.cpp b/scilab/modules/linear_algebra/sci_gateway/cpp/sci_lsq.cpp index 91ae5bc..4bcd9db 100644 --- a/scilab/modules/linear_algebra/sci_gateway/cpp/sci_lsq.cpp +++ b/scilab/modules/linear_algebra/sci_gateway/cpp/sci_lsq.cpp @@ -37,7 +37,7 @@ types::Function::ReturnValue sci_lsq(types::typed_list &in, int _iRetCount, type double* pdTol = NULL; bool bComplexArgs = false; int iRank = 0; - double dblTol = 0.0; + double dblTol = 0.0; if (in.size() < 2 || in.size() > 3) { @@ -57,8 +57,6 @@ types::Function::ReturnValue sci_lsq(types::typed_list &in, int _iRetCount, type return Overload::call(wstFuncName, in, _iRetCount, out); } - pDbl[0] = in[0]->getAs()->clone()->getAs(); - if (in.size() <= 3) { if ((in[1]->isDouble() == false)) @@ -66,7 +64,6 @@ types::Function::ReturnValue sci_lsq(types::typed_list &in, int _iRetCount, type std::wstring wstFuncName = L"%" + in[1]->getShortTypeStr() + L"_lsq"; return Overload::call(wstFuncName, in, _iRetCount, out); } - pDbl[1] = in[1]->getAs()->clone()->getAs(); } if (in.size() == 3) @@ -81,6 +78,9 @@ types::Function::ReturnValue sci_lsq(types::typed_list &in, int _iRetCount, type pdTol = &dblTol; } + pDbl[0] = in[0]->getAs(); + pDbl[1] = in[1]->getAs(); + if (pDbl[0]->getRows() != pDbl[1]->getRows()) { Scierror(265, _("%s: %s and %s must have equal number of rows.\n"), "lsq", "A", "B"); @@ -101,10 +101,18 @@ types::Function::ReturnValue sci_lsq(types::typed_list &in, int _iRetCount, type { bComplexArgs = true; } + + pDbl[0] = pDbl[0]->clone(); + pDbl[1] = pDbl[1]->clone(); + for (int i = 0; i < 2; i++) { if (pDbl[i]->getCols() == -1) { + for (int j=0; j<=i; j++) + { + pDbl[j]->killMe(); + } Scierror(271, _("%s: Size varying argument a*eye(), (arg %d) not allowed here.\n"), "lsq", i + 1); return types::Function::Error; } @@ -114,6 +122,10 @@ types::Function::ReturnValue sci_lsq(types::typed_list &in, int _iRetCount, type pData[i] = (double*)oGetDoubleComplexFromPointer(pDbl[i]->getReal(), pDbl[i]->getImg(), pDbl[i]->getSize()); if (!pData[i]) { + for (int j=0; j<=i; j++) + { + pDbl[j]->killMe(); + } Scierror(999, _("%s: Cannot allocate more memory.\n"), "lsq"); return types::Function::Error; } @@ -137,6 +149,9 @@ types::Function::ReturnValue sci_lsq(types::typed_list &in, int _iRetCount, type int iRet = iLsqM(pData[0], pDbl[0]->getRows(), pDbl[0]->getCols(), pData[1], pDbl[1]->getCols(), bComplexArgs, pResult, pdTol, ((_iRetCount == 2) ? &iRank : NULL)); + pDbl[0]->killMe(); + pDbl[1]->killMe(); + if (iRet != 0) { if (iRet == -1) @@ -148,6 +163,12 @@ types::Function::ReturnValue sci_lsq(types::typed_list &in, int _iRetCount, type Scierror(999, _("%s: LAPACK error n°%d.\n"), "lsq", iRet); } + if (bComplexArgs) + { + vFreeDoubleComplexFromPointer((doublecomplex*)pResult); + vFreeDoubleComplexFromPointer((doublecomplex*)pData[0]); + vFreeDoubleComplexFromPointer((doublecomplex*)pData[1]); + } pDblResult->killMe(); return types::Function::Error; } @@ -171,4 +192,3 @@ types::Function::ReturnValue sci_lsq(types::typed_list &in, int _iRetCount, type return types::Function::OK; } /*--------------------------------------------------------------------------*/ - diff --git a/scilab/modules/linear_algebra/tests/nonreg_tests/bug_15248.tst b/scilab/modules/linear_algebra/tests/nonreg_tests/bug_15248.tst new file mode 100644 index 0000000..57c430f --- /dev/null +++ b/scilab/modules/linear_algebra/tests/nonreg_tests/bug_15248.tst @@ -0,0 +1,27 @@ +// ============================================================================= +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2019 - Stéphane MOTTELET +// +// This file is distributed under the same license as the Scilab package. +// ============================================================================= +// +// <-- CLI SHELL MODE --> +// <-- NO CHECK REF --> +// +// <-- Non-regression test for bug 15248 --> +// +// <-- Bugzilla URL --> +// http://bugzilla.scilab.org/15248 +// +// <-- Short Description --> +// lsq() is leaking memory + +m1 = getmemory(); +a = rand(100,100); +b = rand(100,100); +for i=1:20000 + x = lsq(a,b); +end +clear i a b x +m2 = getmemory(); +assert_checktrue((m1-m2)/m1 <= 0); \ No newline at end of file -- 1.7.9.5