* Bug 15248: lsq() was leaking memory 18/21018/3
Stéphane MOTTELET [Fri, 21 Jun 2019 10:11:17 +0000 (12:11 +0200)]
http://bugzilla.scilab.org/show_bug.cgi?id=15248

Change-Id: I6b1358f7f1509f70e89598782628fcff32922c45

scilab/CHANGES.md
scilab/modules/linear_algebra/sci_gateway/cpp/sci_lsq.cpp
scilab/modules/linear_algebra/tests/nonreg_tests/bug_15248.tst [new file with mode: 0644]

index 1814ebd..a908e35 100644 (file)
@@ -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
index 91ae5bc..4bcd9db 100644 (file)
@@ -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<types::Double>()->clone()->getAs<types::Double>();
-
     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<types::Double>()->clone()->getAs<types::Double>();
     }
 
     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<types::Double>();
+    pDbl[1] = in[1]->getAs<types::Double>();
+
     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 (file)
index 0000000..57c430f
--- /dev/null
@@ -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