diff libinterp/dldfcn/convhulln.cc @ 24260:0f2dc8d6c34d stable

Eliminate possible segfaults related to not cleaning up Qhull workspace. * __delaunayn__.cc (free_qhull_memor): Change function name in error message to "__delaunayn__". * __voronoi__.cc, convhulln.cc (free_qhull_memory): New function with code to clear temporary Qhull memory. * __voronoi__.cc, convhulln.cc (F__voronoi__, Fconvhulln): Use frame.add_fcn to guarantee that free_qhull_memory() is called whenever function exits.
author Rik <rik@octave.org>
date Thu, 16 Nov 2017 11:54:20 -0800
parents 3ac9f9ecfae5
children 554c630c9835
line wrap: on
line diff
--- a/libinterp/dldfcn/convhulln.cc	Wed Nov 15 19:26:38 2017 -0800
+++ b/libinterp/dldfcn/convhulln.cc	Thu Nov 16 11:54:20 2017 -0800
@@ -57,6 +57,19 @@
   std::fclose (f);
 }
 
+static void
+free_qhull_memory ()
+{
+  qh_freeqhull (! qh_ALL);
+
+  int curlong, totlong;
+  qh_memfreeshort (&curlong, &totlong);
+
+  if (curlong || totlong)
+    warning ("convhulln: 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)
 {
@@ -179,6 +192,9 @@
 
   int exitcode = qh_new_qhull (dim, num_points, points.fortran_vec (),
                                ismalloc, cmd_str, outfile, errfile);
+
+  frame.add_fcn (free_qhull_memory);
+
   if (exitcode)
     error ("convhulln: qhull failed");
 
@@ -280,16 +296,6 @@
 
   retval(0) = idx;
 
-  // Free memory from Qhull
-  qh_freeqhull (! qh_ALL);
-
-  int curlong, totlong;
-  qh_memfreeshort (&curlong, &totlong);
-
-  if (curlong || totlong)
-    warning ("convhulln: did not free %d bytes of long memory (%d pieces)",
-             totlong, curlong);
-
   return retval;
 
 #else