diff --git a/src/memory.cpp b/src/memory.cpp
index 0f69561210c500afa16083a023d2953d787b32f3..369f4b5055d348f6226ed804703bfd886fc670fb 100644
--- a/src/memory.cpp
+++ b/src/memory.cpp
@@ -29,91 +29,64 @@ Memory::Memory(LAMMPS *lmp) : Pointers(lmp) {}
    safe malloc 
 ------------------------------------------------------------------------- */
 
-void *Memory::smalloc(int n, const char *name)
+void *Memory::smalloc(bigint nbytes, const char *name)
 {
-  if (n == 0) return NULL;
-  void *ptr = malloc(n);
+  if (nbytes == 0) return NULL;
+
+  void *ptr = malloc(nbytes);
   if (ptr == NULL) {
     char str[128];
-    sprintf(str,"Failed to allocate %d bytes for array %s",n,name);
+    sprintf(str,"Failed to allocate " BIGINT_FORMAT "bytes for array %s",
+	    nbytes,name);
     error->one(str);
   }
   return ptr;
 }
 
-/* ----------------------------------------------------------------------
-   safe free 
-------------------------------------------------------------------------- */
-
-void Memory::sfree(void *ptr)
-{
-  if (ptr == NULL) return;
-  free(ptr);
-}
-
 /* ----------------------------------------------------------------------
    safe realloc 
 ------------------------------------------------------------------------- */
 
-void *Memory::srealloc(void *ptr, int n, const char *name)
+void *Memory::srealloc(void *ptr, bigint nbytes, const char *name)
 {
-  if (n == 0) {
+  if (nbytes == 0) {
     sfree(ptr);
     return NULL;
   }
 
-  ptr = realloc(ptr,n);
+  ptr = realloc(ptr,nbytes);
   if (ptr == NULL) {
     char str[128];
-    sprintf(str,"Failed to reallocate %d bytes for array %s",n,name);
+    sprintf(str,"Failed to reallocate " BIGINT_FORMAT "bytes for array %s",
+	    nbytes,name);
     error->one(str);
   }
   return ptr;
 }
 
 /* ----------------------------------------------------------------------
-   newer routines
+   safe free 
 ------------------------------------------------------------------------- */
 
-void *Memory::smalloc_new(bigint nbytes, const char *name)
+void Memory::sfree(void *ptr)
 {
-  if (nbytes == 0) return NULL;
-
-  void *ptr = malloc(nbytes);
-  if (ptr == NULL) {
-    char str[128];
-    sprintf(str,"Failed to allocate " BIGINT_FORMAT "bytes for array %s",
-	    nbytes,name);
-    error->one(str);
-  }
-  return ptr;
+  if (ptr == NULL) return;
+  free(ptr);
 }
 
-void *Memory::srealloc_new(void *ptr, bigint nbytes, const char *name)
-{
-  if (nbytes == 0) {
-    sfree_new(ptr);
-    return NULL;
-  }
-
-  ptr = realloc(ptr,nbytes);
-  if (ptr == NULL) {
-    char str[128];
-    sprintf(str,"Failed to reallocate " BIGINT_FORMAT "bytes for array %s",
-	    nbytes,name);
-    error->one(str);
-  }
-  return ptr;
-}
+/* ----------------------------------------------------------------------
+   erroneous usage of templated create/grow functions
+------------------------------------------------------------------------- */
 
-void Memory::sfree_new(void *ptr)
+void Memory::fail(const char *name)
 {
-  if (ptr == NULL) return;
-  free(ptr);
+  char str[128];
+  sprintf(str,"Cannot create/grow a vector/array of pointers for %s",name);
+  error->one(str);
 }
 
 /* ----------------------------------------------------------------------
-   older routines
+   older routines, will be deprecated at some point
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
diff --git a/src/memory.h b/src/memory.h
index bf8bd642b32dc64de348e9538a4c2ded45d9c2d6..4eda35b814df05a3787bce17e3bcf1b60f8276e6 100644
--- a/src/memory.h
+++ b/src/memory.h
@@ -14,6 +14,7 @@
 #ifndef LMP_MEMORY_H
 #define LMP_MEMORY_H
 
+#include "error.h"
 #include "pointers.h"
 
 namespace LAMMPS_NS {
@@ -22,11 +23,12 @@ class Memory : protected Pointers {
  public:
   Memory(class LAMMPS *);
 
-  // older routines
-
-  void *smalloc(int n, const char *);
+  void *smalloc(bigint n, const char *);
+  void *srealloc(void *, bigint n, const char *);
   void sfree(void *);
-  void *srealloc(void *, int n, const char *);
+  void fail(const char *);
+
+  // older routines, will be deprecated at some point
 
   double *create_1d_double_array(int, int, const char *);
   void destroy_1d_double_array(double *, int);
@@ -60,16 +62,12 @@ class Memory : protected Pointers {
 
   // newer routines
 
- public:
-  void *smalloc_new(bigint n, const char *);
-  void *srealloc_new(void *, bigint n, const char *);
-  void sfree_new(void *);
-
-
 /* ----------------------------------------------------------------------
-   to avoid code bloat, only use these for int,double,float,char
-   not for int* or double** or arbitrary structs
-   in those cases, just use smalloc,srealloc,sfree directly
+   create/grow/destroy vecs and multidim arrays with contiguous memory blocks
+   only use with primitive data types, e.g. 1d vec of ints, 2d array of doubles
+   cannot use with pointers, e.g. 1d vec of int*, due to mismatched destroy 
+   avoid use with non-primitive data types to avoid code bloat
+   for these other cases, use smalloc/srealloc/sfree directly
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
@@ -80,10 +78,13 @@ class Memory : protected Pointers {
     TYPE *create(TYPE *&array, int n, const char *name)
     {
       bigint nbytes = sizeof(TYPE) * n;
-      array = (TYPE *) smalloc_new(nbytes,name);
+      array = (TYPE *) smalloc(nbytes,name);
       return array;
     };
 
+  template <typename TYPE>
+    TYPE **create(TYPE **&array, int n, const char *name) {fail(name);}
+
 /* ----------------------------------------------------------------------
    grow or shrink 1d array
    if dim is 0, return NULL 
@@ -99,10 +100,13 @@ class Memory : protected Pointers {
       }
       
       bigint nbytes = sizeof(TYPE) * n;
-      array = (TYPE *) srealloc_new(array,nbytes,name);
+      array = (TYPE *) srealloc(array,nbytes,name);
       return array;
     };
 
+  template <typename TYPE>
+    TYPE **grow(TYPE **&array, int n, const char *name) {fail(name);}
+
 /* ----------------------------------------------------------------------
    destroy a 1d array 
 ------------------------------------------------------------------------- */
@@ -110,30 +114,35 @@ class Memory : protected Pointers {
   template <typename TYPE>
     void destroy(TYPE *array) 
     {
-      sfree_new(array);
+      sfree(array);
     };
 
 /* ----------------------------------------------------------------------
    create a 1d array with index from nlo to nhi inclusive 
+   cannot grow it
 ------------------------------------------------------------------------- */
 
   template <typename TYPE>
-    TYPE *create(TYPE *&array, int nlo, int nhi, const char *name) 
+    TYPE *create1d_offset(TYPE *&array, int nlo, int nhi, const char *name) 
     {
       bigint nbytes = sizeof(TYPE) * (nhi-nlo+1);
-      array = (TYPE *) smalloc_new(nbytes,name);
+      array = (TYPE *) smalloc(nbytes,name);
       array = array-nlo;
       return array;
     }
 
+  template <typename TYPE>
+    TYPE **create1d_offset(TYPE **&array, int nlo, int nhi, const char *name)
+    {fail(name);}
+
 /* ----------------------------------------------------------------------
    destroy a 1d array with index offset 
 ------------------------------------------------------------------------- */
 
   template <typename TYPE>
-    void destroy(TYPE *array, int offset) 
+    void destroy1d_offset(TYPE *array, int offset) 
     {
-      if (array) sfree_new(array+offset);
+      if (array) sfree(array+offset);
     }
 
 /* ----------------------------------------------------------------------
@@ -144,9 +153,9 @@ class Memory : protected Pointers {
     TYPE **create(TYPE **&array, int n1, int n2, const char *name) 
     {
       bigint nbytes = sizeof(TYPE) * n1*n2;
-      TYPE *data = (TYPE *) smalloc_new(nbytes,name);
+      TYPE *data = (TYPE *) smalloc(nbytes,name);
       nbytes = sizeof(TYPE *) * n1;
-      array = (TYPE **) smalloc_new(nbytes,name);
+      array = (TYPE **) smalloc(nbytes,name);
       
       int n = 0;
       for (int i = 0; i < n1; i++) {
@@ -156,6 +165,10 @@ class Memory : protected Pointers {
       return array;
     }
 
+  template <typename TYPE>
+    TYPE ***create(TYPE ***&array, int n1, int n2, const char *name)
+    {fail(name);}
+
 /* ----------------------------------------------------------------------
    grow or shrink 1st dim of a 2d array
    last dim must stay the same
@@ -172,9 +185,9 @@ class Memory : protected Pointers {
       }
       
       bigint nbytes = sizeof(TYPE) * n1*n2;
-      TYPE *data = (TYPE *) srealloc_new(array[0],nbytes,name);
+      TYPE *data = (TYPE *) srealloc(array[0],nbytes,name);
       nbytes = sizeof(TYPE *) * n1;
-      array = (TYPE **) srealloc_new(array,nbytes,name);
+      array = (TYPE **) srealloc(array,nbytes,name);
       
       int n = 0;
       for (int i = 0; i < n1; i++) {
@@ -184,6 +197,10 @@ class Memory : protected Pointers {
       return array;
     }
 
+  template <typename TYPE>
+    TYPE ***grow(TYPE ***&array, int n1, int n2, const char *name)
+    {fail(name);}
+
 /* ----------------------------------------------------------------------
    destroy a 2d array 
 ------------------------------------------------------------------------- */
@@ -192,17 +209,18 @@ class Memory : protected Pointers {
     void destroy(TYPE **array)
     {
       if (array == NULL) return;
-      sfree_new(array[0]);
-      sfree_new(array);
+      sfree(array[0]);
+      sfree(array);
     }
 
 /* ----------------------------------------------------------------------
    create a 2d array with 2nd index from n2lo to n2hi inclusive 
+   cannot grow it
 ------------------------------------------------------------------------- */
 
   template <typename TYPE>
-    TYPE **create(TYPE **&array, int n1, int n2lo, int n2hi,
-		  const char *name)
+    TYPE **create2d_offset(TYPE **&array, int n1, int n2lo, int n2hi,
+			   const char *name)
     {
       int n2 = n2hi - n2lo + 1;
       create(array,n1,n2,name);
@@ -210,16 +228,20 @@ class Memory : protected Pointers {
       return array;
     }
 
+  template <typename TYPE>
+    TYPE ***create2d_offset(TYPE ***&array, int n1, int n2lo, int n2hi,
+			    const char *name) {fail(name);}
+
 /* ----------------------------------------------------------------------
    destroy a 2d array with 2nd index offset 
 ------------------------------------------------------------------------- */
 
   template <typename TYPE>
-    void destroy(TYPE **array, int offset)
+    void destroy2d_offset(TYPE **array, int offset)
     {
       if (array == NULL) return;
-      sfree_new(&array[0][offset]);
-      sfree_new(array);
+      sfree(&array[0][offset]);
+      sfree(array);
     }
 
 /* ----------------------------------------------------------------------
@@ -230,11 +252,11 @@ class Memory : protected Pointers {
     TYPE ***create(TYPE ***&array, int n1, int n2, int n3, const char *name) 
     {
       bigint nbytes = sizeof(TYPE) * n1*n2*n3;
-      TYPE *data = (TYPE *) smalloc_new(nbytes,name);
+      TYPE *data = (TYPE *) smalloc(nbytes,name);
       nbytes = sizeof(TYPE *) * n1*n2;
-      TYPE **plane = (TYPE **) smalloc_new(nbytes,name);
+      TYPE **plane = (TYPE **) smalloc(nbytes,name);
       nbytes = sizeof(TYPE **) * n1;
-      array = (TYPE ***) smalloc_new(nbytes,name);
+      array = (TYPE ***) smalloc(nbytes,name);
       
       int i,j;
       int n = 0;
@@ -248,6 +270,10 @@ class Memory : protected Pointers {
       return array;
     }
 
+  template <typename TYPE>
+    TYPE ****create(TYPE ****&array, int n1, int n2, int n3, const char *name) 
+    {fail(name);}
+
 /* ----------------------------------------------------------------------
    grow or shrink 1st dim of a 3d array
    last 2 dims must stay the same
@@ -264,11 +290,11 @@ class Memory : protected Pointers {
       }
       
       bigint nbytes = sizeof(TYPE) * n1*n2*n3;
-      TYPE *data = (TYPE *) srealloc_new(array[0][0],nbytes,name);
+      TYPE *data = (TYPE *) srealloc(array[0][0],nbytes,name);
       nbytes = sizeof(TYPE *) * n1*n2;
-      TYPE **plane = (TYPE **) srealloc_new(array[0],nbytes,name);
+      TYPE **plane = (TYPE **) srealloc(array[0],nbytes,name);
       nbytes = sizeof(TYPE **) * n1;
-      array = (TYPE ***) srealloc_new(array,nbytes,name);
+      array = (TYPE ***) srealloc(array,nbytes,name);
       
       int i,j;
       int n = 0;
@@ -282,6 +308,10 @@ class Memory : protected Pointers {
       return array;
     }
 
+  template <typename TYPE>
+    TYPE ****grow(TYPE ****&array, int n1, int n2, int n3, const char *name) 
+    {fail(name);}
+
 /* ----------------------------------------------------------------------
    destroy a 3d array 
 ------------------------------------------------------------------------- */
@@ -290,30 +320,36 @@ class Memory : protected Pointers {
     void destroy(TYPE ***array) 
     {
       if (array == NULL) return;
-      sfree_new(array[0][0]);
-      sfree_new(array[0]);
-      sfree_new(array);
+      sfree(array[0][0]);
+      sfree(array[0]);
+      sfree(array);
     }
 
 /* ----------------------------------------------------------------------
    create a 3d array with 1st index from n1lo to n1hi inclusive 
+   cannot grow it
 ------------------------------------------------------------------------- */
 
   template <typename TYPE>
-    TYPE ***create(TYPE ***&array, int n1lo, int n1hi, 
-		   int n2, int n3, const char *name)
+    TYPE ***create3d_offset(TYPE ***&array, int n1lo, int n1hi, 
+			    int n2, int n3, const char *name)
     {
       int n1 = n1hi - n1lo + 1;
       create(array,n1,n2,n3,name);
       return array-n1lo;
     }
 
+  template <typename TYPE>
+    TYPE ****create3d_offset(TYPE ****&array, int n1lo, int n1hi, 
+			     int n2, int n3, const char *name)
+    {fail(name);}
+
 /* ----------------------------------------------------------------------
    free a 3d array with 1st index offset 
 ------------------------------------------------------------------------- */
 
   template <typename TYPE>
-    void destroy(TYPE ***array, int offset)
+    void destroy3d_offset(TYPE ***array, int offset)
     {
       if (array) destroy(array+offset);
     }
@@ -323,11 +359,13 @@ class Memory : protected Pointers {
    1st index from n1lo to n1hi inclusive,
    2nd index from n2lo to n2hi inclusive,
    3rd index from n3lo to n3hi inclusive 
+   cannot grow it
 ------------------------------------------------------------------------- */
 
   template <typename TYPE>
-    TYPE ***create(TYPE ***&array, int n1lo, int n1hi, int n2lo, int n2hi,
-		   int n3lo, int n3hi, const char *name)
+    TYPE ***create3d_offset(TYPE ***&array, int n1lo, int n1hi, 
+			    int n2lo, int n2hi, int n3lo, int n3hi,
+			    const char *name)
     {
       int n1 = n1hi - n1lo + 1;
       int n2 = n2hi - n2lo + 1;
@@ -339,17 +377,24 @@ class Memory : protected Pointers {
       return array-n1lo;
     }
 
+  template <typename TYPE>
+    TYPE ****create3d_offset(TYPE ****&array, int n1lo, int n1hi, 
+			     int n2lo, int n2hi, int n3lo, int n3hi,
+			     const char *name)
+    {fail(name);}
+
 /* ----------------------------------------------------------------------
    free a 3d array with all 3 indices offset 
 ------------------------------------------------------------------------- */
 
   template <typename TYPE>
-    void destroy(TYPE ***array, int n1_offset, int n2_offset, int n3_offset)
+    void destroy3d_offset(TYPE ***array, 
+			  int n1_offset, int n2_offset, int n3_offset)
     {
       if (array == NULL) return;
-      sfree_new(&array[n1_offset][n2_offset][n3_offset]);
-      sfree_new(&array[n1_offset][n2_offset]);
-      sfree_new(array + n1_offset);
+      sfree(&array[n1_offset][n2_offset][n3_offset]);
+      sfree(&array[n1_offset][n2_offset]);
+      sfree(array + n1_offset);
     }
 
 /* ----------------------------------------------------------------------
@@ -361,13 +406,13 @@ class Memory : protected Pointers {
 		    const char *name)
     {
       bigint nbytes = sizeof(TYPE) * n1*n2*n3*n4;
-      TYPE *data = (double *) smalloc_new(nbytes,name);
+      TYPE *data = (double *) smalloc(nbytes,name);
       nbytes = sizeof(TYPE *) * n1*n2*n3;
-      TYPE **cube = (double **) smalloc_new(nbytes,name);
+      TYPE **cube = (double **) smalloc(nbytes,name);
       nbytes = sizeof(TYPE **) * n1*n2;
-      TYPE ***plane = (double ***) smalloc_new(nbytes,name);
+      TYPE ***plane = (double ***) smalloc(nbytes,name);
       nbytes = sizeof(TYPE ***) * n1;
-      array = (double ****) smalloc_new(nbytes,name);
+      array = (double ****) smalloc(nbytes,name);
       
       int i,j,k;
       int n = 0;
@@ -384,6 +429,11 @@ class Memory : protected Pointers {
       return array;
     }
 
+  template <typename TYPE>
+    TYPE *****create(TYPE *****&array, int n1, int n2, int n3, int n4,
+		     const char *name)
+    {fail(name);}
+
 /* ----------------------------------------------------------------------
    destroy a 4d array 
 ------------------------------------------------------------------------- */
@@ -392,10 +442,10 @@ class Memory : protected Pointers {
     void destroy(TYPE ****array)
     {
       if (array == NULL) return;
-      sfree_new(array[0][0][0]);
-      sfree_new(array[0][0]);
-      sfree_new(array[0]);
-      sfree_new(array);
+      sfree(array[0][0][0]);
+      sfree(array[0][0]);
+      sfree(array[0]);
+      sfree(array);
     }
 
 /* ----------------------------------------------------------------------