gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r37907 - in gnunet/src: include util


From: gnunet
Subject: [GNUnet-SVN] r37907 - in gnunet/src: include util
Date: Thu, 8 Sep 2016 00:31:06 +0200

Author: teichm
Date: 2016-09-08 00:31:05 +0200 (Thu, 08 Sep 2016)
New Revision: 37907

Modified:
   gnunet/src/include/gnunet_common.h
   gnunet/src/util/common_allocation.c
   gnunet/src/util/test_common_allocation.c
Log:
gnunetutil: add 2d and 3d allocation including tests


Modified: gnunet/src/include/gnunet_common.h
===================================================================
--- gnunet/src/include/gnunet_common.h  2016-09-07 17:45:15 UTC (rev 37906)
+++ gnunet/src/include/gnunet_common.h  2016-09-07 22:31:05 UTC (rev 37907)
@@ -800,6 +800,29 @@
 
 /**
  * @ingroup memory
+ * Allocate a size @a n times @a m array
+ * with structs or unions of the given @a type.
+ *
+ * @param n size of the first dimension
+ * @param m size of the second dimension
+ * @param type name of the struct or union, i.e. pass 'struct Foo'.
+ */
+#define GNUNET_new_array_2d(n, m, type) (type **) GNUNET_xnew_array_2d_ (n, m, 
sizeof (type))
+
+/**
+ * @ingroup memory
+ * Allocate a size @a n times @a m times @a o array
+ * with structs or unions of the given @a type.
+ *
+ * @param n size of the first dimension
+ * @param m size of the second dimension
+ * @param o size of the third dimension
+ * @param type name of the struct or union, i.e. pass 'struct Foo'.
+ */
+#define GNUNET_new_array_3d(n, m, o, type) (type ***) GNUNET_xnew_array_3d_ 
(n, m, o, sizeof (type))
+
+/**
+ * @ingroup memory
  * Wrapper around malloc. Allocates size bytes of memory.
  * The memory will be zero'ed out.
  *
@@ -968,6 +991,39 @@
 
 
 /**
+ * Allocate memory for a two dimensional array in one block
+ * and set up pointers. Aborts if no more memory is available.
+ * Don't use GNUNET_xnew_array_2d_ directly. Use the
+ * #GNUNET_new_array_2d macro.
+ * The memory of the elements will be zero'ed out.
+ *
+ * @param n size of the first dimension
+ * @param m size of the second dimension
+ * @param elementSize size of a single element in bytes
+ * @return allocated memory, never NULL
+ */
+void **
+GNUNET_xnew_array_2d_ (size_t n, size_t m, size_t elementSize);
+
+
+/**
+ * Allocate memory for a three dimensional array in one block
+ * and set up pointers. Aborts if no more memory is available.
+ * Don't use GNUNET_xnew_array_3d_ directly. Use the
+ * #GNUNET_new_array_3d macro.
+ * The memory of the elements will be zero'ed out.
+ *
+ * @param n size of the first dimension
+ * @param m size of the second dimension
+ * @param o size of the third dimension
+ * @param elementSize size of a single element in bytes
+ * @return allocated memory, never NULL
+ */
+void ***
+GNUNET_xnew_array_3d_ (size_t n, size_t m, size_t o, size_t elementSize);
+
+
+/**
  * Allocate and initialize memory. Checks the return value, aborts if no more
  * memory is available.  Don't use GNUNET_xmemdup_ directly. Use the
  * #GNUNET_memdup macro.

Modified: gnunet/src/util/common_allocation.c
===================================================================
--- gnunet/src/util/common_allocation.c 2016-09-07 17:45:15 UTC (rev 37906)
+++ gnunet/src/util/common_allocation.c 2016-09-07 22:31:05 UTC (rev 37907)
@@ -86,6 +86,71 @@
 
 
 /**
+ * Allocate memory for a two dimensional array in one block
+ * and set up pointers. Aborts if no more memory is available.
+ * Don't use GNUNET_xnew_array_2d_ directly. Use the
+ * #GNUNET_new_array_2d macro.
+ * The memory of the elements will be zero'ed out.
+ *
+ * @param n size of the first dimension
+ * @param m size of the second dimension
+ * @param elementSize size of a single element in bytes
+ * @return allocated memory, never NULL
+ */
+void **
+GNUNET_xnew_array_2d_ (size_t n, size_t m, size_t elementSize)
+{
+       /* use char pointer internally to avoid void pointer arithmetic 
warnings */
+       char **ret = GNUNET_malloc (n * sizeof (void *) +  /* 1. dim header */
+                                   n * m * elementSize);  /* element data */
+
+       for (size_t i = 0; i < n; i++)
+               ret[i] = (char *)ret +          /* base address */
+                        n * sizeof (void *) +  /* skip 1. dim header */
+                        i * m * elementSize;   /* skip to 2. dim row header */
+       return (void **)ret;
+}
+
+
+/**
+ * Allocate memory for a three dimensional array in one block
+ * and set up pointers. Aborts if no more memory is available.
+ * Don't use GNUNET_xnew_array_3d_ directly. Use the
+ * #GNUNET_new_array_3d macro.
+ * The memory of the elements will be zero'ed out.
+ *
+ * @param n size of the first dimension
+ * @param m size of the second dimension
+ * @param o size of the third dimension
+ * @param elementSize size of a single element in bytes
+ * @return allocated memory, never NULL
+ */
+void ***
+GNUNET_xnew_array_3d_ (size_t n, size_t m, size_t o, size_t elementSize)
+{
+       /* use char pointer internally to avoid void pointer arithmetic 
warnings */
+       char ***ret = GNUNET_malloc (n * sizeof (void **) +     /* 1. dim 
header */
+                                    n * m * sizeof (void *) +  /* 2. dim 
header */
+                                    n * m * o * elementSize);  /* element data 
*/
+
+       for (size_t i = 0; i < n; i++)
+       {
+               /* need to cast to (char *) temporarily for byte level acuracy 
*/
+               ret[i] = (char **)((char *)ret +             /* base address */
+                                  n * sizeof (void **) +    /* skip 1. dim 
header */
+                                  i * m * sizeof (void *)); /* skip to 2. dim 
header */
+               for (size_t j = 0; j < m; j++)
+                       ret[i][j] = (char *)ret +              /* base address 
*/
+                                   n * sizeof (void **) +     /* skip 1. dim 
header */
+                                   n * m * sizeof (void *) +  /* skip 2. dim 
header */
+                                   i * m * o * elementSize +  /* skip to 2. 
dim part */
+                                       j * o * elementSize;   /* skip to 3. 
dim row data */
+       }
+       return (void ***)ret;
+}
+
+
+/**
  * Allocate and initialize memory. Checks the return value, aborts if no more
  * memory is available.  Don't use #GNUNET_xmemdup_() directly. Use the
  * GNUNET_memdup() macro.

Modified: gnunet/src/util/test_common_allocation.c
===================================================================
--- gnunet/src/util/test_common_allocation.c    2016-09-07 17:45:15 UTC (rev 
37906)
+++ gnunet/src/util/test_common_allocation.c    2016-09-07 22:31:05 UTC (rev 
37907)
@@ -30,6 +30,8 @@
 {
 #define MAX_TESTVAL 1024
   char *ptrs[MAX_TESTVAL];
+  unsigned int **a2;
+  char ***a3;
   int i;
   int j;
   int k;
@@ -93,7 +95,35 @@
   if (ptrs[0] != NULL)
     return 9;
 
+       /* GNUNET_new_array_2d tests */
+       a2 = GNUNET_new_array_2d (17, 22, unsigned int);
+       for (i = 0; i < 17; i++)
+       {
+               for (j = 0; j < 22; j++)
+               {
+                       if (0 != a2[i][j])
+                               return 10;
+                       a2[i][j] = i * 100 + j;
+               }
+       }
+       free (a2);
 
+       /* GNUNET_new_array_3d tests */
+       a3 = GNUNET_new_array_3d (2, 3, 4, char);
+       for (i = 0; i < 2; i++)
+       {
+               for (j = 0; j < 3; j++)
+               {
+                       for (k = 0; k < 4; k++)
+                       {
+                               if (0 != a3[i][j][k])
+                                       return 11;
+                               a3[i][j][k] = i * 100 + j * 10 + k;
+                       }
+               }
+       }
+       free (a3);
+
   return 0;
 }
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]