changeset 24258:bffbc95fa72b stable

Fix segfault in delaunayn when Qhull memory is not properly cleared (bug #52410). * __delaunayn__.cc (free_qhull_memory): New function with code to clear temporary Qhull memory. * __delaunayn__.cc (F__delaunayn__): Use frame.add_fcn to guarantee that free_qhull_memory() is called whenever function exits.
author Rik <rik@octave.org>
date Wed, 15 Nov 2017 19:26:38 -0800
parents 4283c4c2fcb6
children 676bf5131971 0f2dc8d6c34d
files libinterp/dldfcn/__delaunayn__.cc
diffstat 1 files changed, 16 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/dldfcn/__delaunayn__.cc	Wed Nov 15 15:21:45 2017 -0800
+++ b/libinterp/dldfcn/__delaunayn__.cc	Wed Nov 15 19:26:38 2017 -0800
@@ -68,6 +68,19 @@
   std::fclose (f);
 }
 
+static void
+free_qhull_memory ()
+{
+  qh_freeqhull (! qh_ALL);
+
+  int curlong, totlong;
+  qh_memfreeshort (&curlong, &totlong);
+
+  if (curlong || totlong)
+    warning ("__delaunay__: did not free %d bytes of long memory (%d pieces)",
+             totlong, curlong);
+}
+
 static bool
 octave_qhull_dims_ok (octave_idx_type dim, octave_idx_type n, const char *who)
 {
@@ -163,6 +176,9 @@
 
       int exitcode = qh_new_qhull (dim, n, pt_array,
                                    ismalloc, flags, outfile, errfile);
+
+      frame.add_fcn (free_qhull_memory);
+
       if (exitcode)
         error ("__delaunayn__: qhull failed");
 
@@ -204,16 +220,6 @@
 
           retval(0) = simpl;
         }
-
-      // Free memory from Qhull
-      qh_freeqhull (! qh_ALL);
-
-      int curlong, totlong;
-      qh_memfreeshort (&curlong, &totlong);
-
-      if (curlong || totlong)
-        warning ("__delaunay__: did not free %d bytes of long memory (%d pieces)",
-                 totlong, curlong);
     }
   else if (n == dim + 1)
     {