diff --git a/y/Array.h b/z/Array.h
index 86dcee6..8d4972d 100644
--- a/y/Array.h
+++ b/z/Array.h
@@ -125,6 +125,15 @@
 // forward declare template with visibility attribute
 template <typename T> class OCTARRAY_API Array;
 
+using deleter_t = void (*)(void *);
+
+template <typename T>
+void
+delete_array (void* p)
+{
+  delete[] static_cast<T *>(p);
+};
+
 template <typename T>
 class
 Array
@@ -139,16 +148,17 @@ protected:
     T *m_data;
     octave_idx_type m_len;
     octave::refcount<octave_idx_type> m_count;
+    deleter_t m_deleter;
 
     ArrayRep (T *d, octave_idx_type l)
-      : m_data (new T [l]), m_len (l), m_count (1)
+      : m_data (new T [l]), m_len (l), m_count (1), m_deleter (delete_array<T>)
     {
       std::copy_n (d, l, m_data);
     }
 
     template <typename U>
     ArrayRep (U *d, octave_idx_type l)
-      : m_data (new T [l]), m_len (l), m_count (1)
+      : m_data (new T [l]), m_len (l), m_count (1), m_deleter (delete_array<T>)
     {
       std::copy_n (d, l, m_data);
     }
@@ -156,28 +166,28 @@ protected:
     // Use new instead of setting data to 0 so that fortran_vec and
     // data always return valid addresses, even for zero-size arrays.
 
-    ArrayRep (void) : m_data (new T [0]), m_len (0), m_count (1) { }
+    ArrayRep (void) : m_data (new T [0]), m_len (0), m_count (1),m_deleter (delete_array<T>) { }
 
     explicit ArrayRep (octave_idx_type n)
-      : m_data (new T [n]), m_len (n), m_count (1) { }
+      : m_data (new T [n]), m_len (n), m_count (1), m_deleter (delete_array<T>) { }
 
     explicit ArrayRep (octave_idx_type n, const T& val)
-      : m_data (new T [n]), m_len (n), m_count (1)
+      : m_data (new T [n]), m_len (n), m_count (1), m_deleter (delete_array<T>)
     {
       std::fill_n (m_data, n, val);
     }
 
-    explicit ArrayRep (T *ptr, const dim_vector& dv)
-      : m_data (ptr), m_len (dv.safe_numel ()), m_count (1)
+    explicit ArrayRep (T *ptr, const dim_vector& dv, deleter_t del)
+      : m_data (ptr), m_len (dv.safe_numel ()), m_count (1), m_deleter (del)
     { }
 
     ArrayRep (const ArrayRep& a)
-      : m_data (new T [a.m_len]), m_len (a.m_len), m_count (1)
+      : m_data (new T [a.m_len]), m_len (a.m_len), m_count (1), m_deleter (delete_array<T>)
     {
       std::copy_n (a.m_data, a.m_len, m_data);
     }
 
-    ~ArrayRep (void) { delete [] m_data; }
+    ~ArrayRep (void) { m_deleter (m_data); }
 
     octave_idx_type numel (void) const { return m_len; }
 
@@ -281,9 +291,9 @@ public:
   // object is deleted.  The dimension vector DV must be consistent with
   // the size of the allocated PTR array.
 
-  explicit Array (T *ptr, const dim_vector& dv)
+  explicit Array (T *ptr, const dim_vector& dv, deleter_t del)
     : m_dimensions (dv),
-      m_rep (new typename Array<T>::ArrayRep (ptr, dv)),
+      m_rep (new typename Array<T>::ArrayRep (ptr, dv, del)),
       m_slice_data (m_rep->m_data), m_slice_len (m_rep->m_len)
   {
     m_dimensions.chop_trailing_singletons ();
diff --git a/y/Sparse.cc b/z/Sparse.cc
index 39eeb3a..587c559 100644
--- a/y/Sparse.cc
+++ b/z/Sparse.cc
@@ -160,14 +160,16 @@ Sparse<T>::SparseRep::change_length (octave_idx_type nz)
       octave_idx_type *new_ridx = new octave_idx_type [nz];
       std::copy_n (m_ridx, min_nzmax, new_ridx);
 
-      delete [] m_ridx;
+      m_ridx_deleter (m_ridx);
       m_ridx = new_ridx;
+      m_ridx_deleter = delete_array<octave_idx_type>;
 
       T *new_data = new T [nz];
       std::copy_n (m_data, min_nzmax, new_data);
 
-      delete [] m_data;
+      m_data_deleter (m_data);
       m_data = new_data;
+      m_data_deleter = delete_array<T>;
 
       m_nzmax = nz;
     }
@@ -1019,8 +1021,9 @@ Sparse<T>::resize (octave_idx_type r, octave_idx_type c)
     {
       octave_idx_type *new_cidx = new octave_idx_type [c+1];
       std::copy_n (m_rep->m_cidx, std::min (c, m_rep->m_ncols) + 1, new_cidx);
-      delete [] m_rep->m_cidx;
+      m_rep->m_cidx_deleter (m_rep->m_cidx);
       m_rep->m_cidx = new_cidx;
+      m_rep->m_cidx_deleter = delete_array<octave_idx_type>;
 
       if (c > m_rep->m_ncols)
         std::fill_n (m_rep->m_cidx + m_rep->m_ncols + 1, c - m_rep->m_ncols,
diff --git a/y/Sparse.h b/z/Sparse.h
index c9d9a6a..394042f 100644
--- a/y/Sparse.h
+++ b/z/Sparse.h
@@ -38,6 +38,10 @@
 class PermMatrix;
 template <typename T> class Array;
 
+template <typename T> void delete_array (void* p);
+
+using deleter_t = void (*)(void *);
+
 // Two dimensional sparse class.  Handles the reference counting for
 // all the derived classes.
 
@@ -68,24 +72,36 @@ protected:
     octave_idx_type m_nrows;
     octave_idx_type m_ncols;
     octave::refcount<octave_idx_type> m_count;
+    deleter_t m_data_deleter;
+    deleter_t m_ridx_deleter;
+    deleter_t m_cidx_deleter;
 
     SparseRep (void)
       : m_data (new T [1]), m_ridx (new octave_idx_type [1] {}),
         m_cidx (new octave_idx_type [1] {}),
-        m_nzmax (1), m_nrows (0), m_ncols (0), m_count (1)
+        m_nzmax (1), m_nrows (0), m_ncols (0), m_count (1),
+        m_data_deleter (delete_array<T>),
+        m_ridx_deleter (delete_array<octave_idx_type>),
+        m_cidx_deleter (delete_array<octave_idx_type>)
     { }
 
     SparseRep (octave_idx_type n)
       : m_data (new T [1]), m_ridx (new octave_idx_type [1] {}),
         m_cidx (new octave_idx_type [n+1] {}),
-        m_nzmax (1), m_nrows (n), m_ncols (n), m_count (1)
+        m_nzmax (1), m_nrows (n), m_ncols (n), m_count (1),
+        m_data_deleter (delete_array<T>),
+        m_ridx_deleter (delete_array<octave_idx_type>),
+        m_cidx_deleter (delete_array<octave_idx_type>)
     { }
 
     SparseRep (octave_idx_type nr, octave_idx_type nc, octave_idx_type nz = 1)
       : m_data (nz > 0 ? new T [nz] : new T [1]),
         m_ridx (nz > 0 ? new octave_idx_type [nz] {} : new octave_idx_type [1] {}),
         m_cidx (new octave_idx_type [nc+1] {}),
-        m_nzmax (nz > 0 ? nz : 1), m_nrows (nr), m_ncols (nc), m_count (1)
+        m_nzmax (nz > 0 ? nz : 1), m_nrows (nr), m_ncols (nc), m_count (1),
+        m_data_deleter (delete_array<T>),
+        m_ridx_deleter (delete_array<octave_idx_type>),
+        m_cidx_deleter (delete_array<octave_idx_type>)
     { }
 
     SparseRep (octave_idx_type nr, octave_idx_type nc, octave_idx_type nz,
@@ -93,7 +109,10 @@ protected:
       : m_data (new T [nz]),
         m_ridx (new octave_idx_type [nz] {}),
         m_cidx (new octave_idx_type [nc+1] {}),
-        m_nzmax (nz), m_nrows (nr), m_ncols (nc), m_count (1)
+        m_nzmax (nz), m_nrows (nr), m_ncols (nc), m_count (1),
+        m_data_deleter (delete_array<T>),
+        m_ridx_deleter (delete_array<octave_idx_type>),
+        m_cidx_deleter (delete_array<octave_idx_type>)
     {
       std::copy_n (d, nz, m_data);
       std::copy_n (r, nz, m_ridx);
@@ -106,7 +125,10 @@ protected:
       : m_data (new T [nz]),
         m_ridx (new octave_idx_type [nz] {}),
         m_cidx (new octave_idx_type [nc+1] {}),
-        m_nzmax (nz), m_nrows (nr), m_ncols (nc), m_count (1)
+        m_nzmax (nz), m_nrows (nr), m_ncols (nc), m_count (1),
+        m_data_deleter (delete_array<T>),
+        m_ridx_deleter (delete_array<octave_idx_type>),
+        m_cidx_deleter (delete_array<octave_idx_type>)
     {
       std::copy_n (d, nz, m_data);
       std::copy_n (r, nz, m_ridx);
@@ -115,15 +137,22 @@ protected:
 
     template <typename U>
     SparseRep (const dim_vector& dv, octave_idx_type nz,
-               U *d, octave_idx_type *r, octave_idx_type *c)
+               U *d, octave_idx_type *r, octave_idx_type *c,
+               deleter_t d_del, deleter_t r_del, deleter_t c_del)
       : m_data (d), m_ridx (r), m_cidx (c),
-        m_nzmax (nz), m_nrows (dv(0)), m_ncols (dv(1)), m_count (1)
+        m_nzmax (nz), m_nrows (dv(0)), m_ncols (dv(1)), m_count (1),
+        m_data_deleter (d_del),
+        m_ridx_deleter (r_del),
+        m_cidx_deleter (c_del)
     { }
 
     SparseRep (const SparseRep& a)
       : m_data (new T [a.m_nzmax]), m_ridx (new octave_idx_type [a.m_nzmax]),
         m_cidx (new octave_idx_type [a.m_ncols + 1]),
-        m_nzmax (a.m_nzmax), m_nrows (a.m_nrows), m_ncols (a.m_ncols), m_count (1)
+        m_nzmax (a.m_nzmax), m_nrows (a.m_nrows), m_ncols (a.m_ncols), m_count (1),
+        m_data_deleter (delete_array<T>),
+        m_ridx_deleter (delete_array<octave_idx_type>),
+        m_cidx_deleter (delete_array<octave_idx_type>)
     {
       octave_idx_type nz = a.nnz ();
       std::copy_n (a.m_data, nz, m_data);
@@ -131,7 +160,12 @@ protected:
       std::copy_n (a.m_cidx, m_ncols + 1, m_cidx);
     }
 
-    ~SparseRep (void) { delete [] m_data; delete [] m_ridx; delete [] m_cidx; }
+    ~SparseRep (void)
+    {
+      m_data_deleter (m_data);
+      m_ridx_deleter (m_ridx);
+      m_cidx_deleter (m_cidx);
+    }
 
     octave_idx_type nzmax (void) const { return m_nzmax; }
     octave_idx_type nnz (void) const { return m_cidx[m_ncols]; }
@@ -233,8 +267,10 @@ public:
   // of the allocated PTR, CIDX, and RIDX arrays.
 
   Sparse (const dim_vector& dv, octave_idx_type nz,
-          T *ptr, octave_idx_type *ridx, octave_idx_type *cidx)
-    : m_rep (new typename Sparse<T>::SparseRep (dv, nz, ptr, ridx, cidx)),
+          T *ptr, octave_idx_type *ridx, octave_idx_type *cidx,
+          deleter_t d_del, deleter_t r_del, deleter_t c_del)
+    : m_rep (new typename Sparse<T>::SparseRep (dv, nz, ptr, ridx, cidx,
+                                                d_del, r_del, c_del)),
       m_dimensions (dv)
   { }
 
diff --git a/y/mex.cc b/z/mex.cc
index 16d6313..697afa1 100644
--- a/y/mex.cc
+++ b/z/mex.cc
@@ -2048,7 +2048,7 @@ protected:
   {
     ELT_T *ppr = static_cast<ELT_T *> (m_pr);
 
-    Array<ELT_T> val (ppr, dv);
+    Array<ELT_T> val (ppr, dv, std::free);
 
     maybe_disown_ptr (m_pr);
 
@@ -2065,7 +2065,7 @@ protected:
     ELT_T *ppr = static_cast<ELT_T *> (m_pr);
 
 #if 0
-    ARRAY_T val (ppr, dv);
+    ARRAY_T val (ppr, dv, std::free);
 
     maybe_disown_ptr (m_pr);
 #else
@@ -2476,7 +2476,7 @@ protected:
     ELT_T *ppr = static_cast<ELT_T *> (m_pr);
 
     Sparse<ELT_T> val (dv, static_cast<octave_idx_type> (m_nzmax),
-                       ppr, m_ir, m_jc);
+                       ppr, m_ir, m_jc, std::free, std::free, std::free);
 
     maybe_disown_ptr (m_pr);
     maybe_disown_ptr (m_ir);
