about summary refs log tree commit diff
path: root/lib/libpm.c
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2010-06-27 19:52:28 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2010-06-27 19:52:28 +0000
commitb64acd496028fb582d052f9e7fccfe6d542f85ca (patch)
treef857dd13be86692b13199c0da7bdfe343b8e30a2 /lib/libpm.c
parente0d1d6e5f3836c0f5b2bf20a8666b312802a540e (diff)
downloadnetpbm-mirror-b64acd496028fb582d052f9e7fccfe6d542f85ca.tar.gz
netpbm-mirror-b64acd496028fb582d052f9e7fccfe6d542f85ca.tar.xz
netpbm-mirror-b64acd496028fb582d052f9e7fccfe6d542f85ca.zip
Add MALLOCARRAY2
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1249 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'lib/libpm.c')
-rw-r--r--lib/libpm.c149
1 files changed, 14 insertions, 135 deletions
diff --git a/lib/libpm.c b/lib/libpm.c
index b8a322a1..6c01148c 100644
--- a/lib/libpm.c
+++ b/lib/libpm.c
@@ -311,140 +311,26 @@ pm_freerow(void * const itrow) {
 
 
 
-static void
-allocarrayNoHeap(unsigned char ** const rowIndex,
-                 unsigned int     const cols,
-                 unsigned int     const rows,
-                 unsigned int     const size,
-                 const char **    const errorP) {
-
-    if (cols != 0 && UINT_MAX / cols < size)
-        asprintfN(errorP,
-                  "Arithmetic overflow multiplying %u by %u to get the "
-                  "size of a row to allocate.", cols, size);
-    else {
-        unsigned int rowsDone;
-
-        rowsDone = 0;
-        *errorP = NULL;
-
-        while (rowsDone < rows && !*errorP) {
-            unsigned char * const rowSpace = mallocz(cols * size);
-            if (rowSpace == NULL)
-                asprintfN(errorP,
-                          "Unable to allocate a %u-column by %u byte row",
-                          cols, size);
-            else
-                rowIndex[rowsDone++] = rowSpace;
-        }
-        if (*errorP) {
-            unsigned int row;
-            for (row = 0; row < rowsDone; ++row)
-                free(rowIndex[row]);
-        }
-    }
-}
-
-
-
-static unsigned char *
-allocRowHeap(unsigned int const cols,
-             unsigned int const rows,
-             unsigned int const size) {
-/*----------------------------------------------------------------------------
-   Allocate a row heap.  That's a chunk of memory for use in a
-   pm_allocarray two-dimensional array to contain the rows.
-
-   The heap must fit 'rows' rows of 'cols' columns each of elements
-   'size' bytes in size.
-
-   Return NULL if we can't get the memory.
------------------------------------------------------------------------------*/
-    unsigned char * retval;
-
-    if (cols != 0 && rows != 0 && UINT_MAX / cols / rows < size)
-        /* Too big even to request the memory ! */
-        retval = NULL;
-    else
-        retval = mallocz(rows * cols * size);
-
-    return retval;
-}
-
-
-
 char **
 pm_allocarray(int const cols,
               int const rows,
-              int const size )  {
+              int const elementSize ) {
 /*----------------------------------------------------------------------------
-   Allocate an array of 'rows' rows of 'cols' columns each, with each
-   element 'size' bytes.
-
-   We use the C multidimensional array paradigm:  The array is a row
-   index (array of pointers to rows) plus an array of elements for each
-   of those rows.  So a[row][col] gives you the element of the two
-   dimensional array at Row 'row', Column 'col'.
-
-   But we use a special variation on that where we tack on an extra element to
-   the row index to indicate the format of the array.
-
-   We do NOT TAKE CARE OF ALIGNMENT.  Alignment of the elements is only one
-   byte even if 'size' indicates elements are 4 bytes each.  Normally, it
-   would be a good idea to align such elements to 4 byte boundaries (address
-   is a multiple of 4).  But we don't, so watch out.
-
-   We have two ways of allocating the space: fragmented and
-   unfragmented.  In both, the row index (plus the extra element) is
-   in one block of memory.  In the fragmented format, each row is
-   also in an independent memory block, and the extra row pointer is
-   NULL.  In the unfragmented format, all the rows are in a single
-   block of memory called the row heap and the extra row pointer is
-   the address of that block.
-
-   We use unfragmented format if possible, but if the allocation of the
-   row heap fails, we fall back to fragmented.
------------------------------------------------------------------------------*/
-    unsigned char ** rowIndex;
-    const char * error;
-
-    MALLOCARRAY(rowIndex, rows + 1);
-    if (rowIndex == NULL)
-        asprintfN(&error,
-                  "out of memory allocating row index (%u rows) for an array",
-                  rows);
-    else {
-        unsigned char * rowheap;
+   This is for backward compatibility.  MALLOCARRAY2 is usually better.
 
-        rowheap = allocRowHeap(cols, rows, size);
+   A problem with pm_allocarray() is that its return type is char **
+   even though 'elementSize' can be other than 1.  So users have
+   traditionally type cast the result.  In the old days, that was just
+   messy; modern compilers can produce the wrong code if you do that.
+-----------------------------------------------------------------------------*/
+    char ** retval;
+    void * result;
 
-        if (rowheap) {
-            /* It's unfragmented format */
+    pm_mallocarray2(&result, rows, cols, elementSize);
 
-            rowIndex[rows] = rowheap;  /* Declare it unfragmented format */
+    retval = result;
 
-            if (rowheap) {
-                unsigned int row;
-                
-                for (row = 0; row < rows; ++row)
-                    rowIndex[row] = &(rowheap[row * cols * size]);
-            }
-            error = NULL;
-        } else {
-            /* We couldn't get the whole heap in one block, so try fragmented
-               format.
-            */
-            rowIndex[rows] = NULL;   /* Declare it fragmented format */
-            
-            allocarrayNoHeap(rowIndex, cols, rows, size, &error);
-        }
-    }
-    if (error) {
-        pm_errormsg("Couldn't allocate %u-row array.  %s", rows, error);
-        strfree(error);
-        pm_longjmp();
-    }
-    return (char **)rowIndex;
+    return retval;
 }
 
 
@@ -453,16 +339,9 @@ void
 pm_freearray(char ** const rowIndex, 
              int     const rows) {
 
-    void * const rowheap = rowIndex[rows];
+    void * const rowIndexVoid = rowIndex;
 
-    if (rowheap != NULL)
-        free(rowheap);
-    else {
-        unsigned int row;
-        for (row = 0; row < rows; ++row)
-            pm_freerow(rowIndex[row]);
-    }
-    free(rowIndex);
+    pm_freearray2(rowIndexVoid);
 }