aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMarkus Teich <teichm@fs.tum.de>2016-09-07 22:31:05 +0000
committerMarkus Teich <teichm@fs.tum.de>2016-09-07 22:31:05 +0000
commit2a6a2e9713184f13df1972ca3b10004f0bccd282 (patch)
tree596a07b4b281eeffc8d0293b8e932ff48b593351 /src
parent939d0142629866734169ed7b2741aac7edd32cfc (diff)
downloadgnunet-2a6a2e9713184f13df1972ca3b10004f0bccd282.tar.gz
gnunet-2a6a2e9713184f13df1972ca3b10004f0bccd282.zip
gnunetutil: add 2d and 3d allocation including tests
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_common.h56
-rw-r--r--src/util/common_allocation.c65
-rw-r--r--src/util/test_common_allocation.c30
3 files changed, 151 insertions, 0 deletions
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h
index cc42cac86..2438b179c 100644
--- a/src/include/gnunet_common.h
+++ b/src/include/gnunet_common.h
@@ -800,6 +800,29 @@ GNUNET_ntoh_double (double d);
800 800
801/** 801/**
802 * @ingroup memory 802 * @ingroup memory
803 * Allocate a size @a n times @a m array
804 * with structs or unions of the given @a type.
805 *
806 * @param n size of the first dimension
807 * @param m size of the second dimension
808 * @param type name of the struct or union, i.e. pass 'struct Foo'.
809 */
810#define GNUNET_new_array_2d(n, m, type) (type **) GNUNET_xnew_array_2d_ (n, m, sizeof (type))
811
812/**
813 * @ingroup memory
814 * Allocate a size @a n times @a m times @a o array
815 * with structs or unions of the given @a type.
816 *
817 * @param n size of the first dimension
818 * @param m size of the second dimension
819 * @param o size of the third dimension
820 * @param type name of the struct or union, i.e. pass 'struct Foo'.
821 */
822#define GNUNET_new_array_3d(n, m, o, type) (type ***) GNUNET_xnew_array_3d_ (n, m, o, sizeof (type))
823
824/**
825 * @ingroup memory
803 * Wrapper around malloc. Allocates size bytes of memory. 826 * Wrapper around malloc. Allocates size bytes of memory.
804 * The memory will be zero'ed out. 827 * The memory will be zero'ed out.
805 * 828 *
@@ -968,6 +991,39 @@ GNUNET_xmalloc_ (size_t size, const char *filename, int linenumber);
968 991
969 992
970/** 993/**
994 * Allocate memory for a two dimensional array in one block
995 * and set up pointers. Aborts if no more memory is available.
996 * Don't use GNUNET_xnew_array_2d_ directly. Use the
997 * #GNUNET_new_array_2d macro.
998 * The memory of the elements will be zero'ed out.
999 *
1000 * @param n size of the first dimension
1001 * @param m size of the second dimension
1002 * @param elementSize size of a single element in bytes
1003 * @return allocated memory, never NULL
1004 */
1005void **
1006GNUNET_xnew_array_2d_ (size_t n, size_t m, size_t elementSize);
1007
1008
1009/**
1010 * Allocate memory for a three dimensional array in one block
1011 * and set up pointers. Aborts if no more memory is available.
1012 * Don't use GNUNET_xnew_array_3d_ directly. Use the
1013 * #GNUNET_new_array_3d macro.
1014 * The memory of the elements will be zero'ed out.
1015 *
1016 * @param n size of the first dimension
1017 * @param m size of the second dimension
1018 * @param o size of the third dimension
1019 * @param elementSize size of a single element in bytes
1020 * @return allocated memory, never NULL
1021 */
1022void ***
1023GNUNET_xnew_array_3d_ (size_t n, size_t m, size_t o, size_t elementSize);
1024
1025
1026/**
971 * Allocate and initialize memory. Checks the return value, aborts if no more 1027 * Allocate and initialize memory. Checks the return value, aborts if no more
972 * memory is available. Don't use GNUNET_xmemdup_ directly. Use the 1028 * memory is available. Don't use GNUNET_xmemdup_ directly. Use the
973 * #GNUNET_memdup macro. 1029 * #GNUNET_memdup macro.
diff --git a/src/util/common_allocation.c b/src/util/common_allocation.c
index 71dd46bf1..f0299a223 100644
--- a/src/util/common_allocation.c
+++ b/src/util/common_allocation.c
@@ -86,6 +86,71 @@ GNUNET_xmalloc_ (size_t size,
86 86
87 87
88/** 88/**
89 * Allocate memory for a two dimensional array in one block
90 * and set up pointers. Aborts if no more memory is available.
91 * Don't use GNUNET_xnew_array_2d_ directly. Use the
92 * #GNUNET_new_array_2d macro.
93 * The memory of the elements will be zero'ed out.
94 *
95 * @param n size of the first dimension
96 * @param m size of the second dimension
97 * @param elementSize size of a single element in bytes
98 * @return allocated memory, never NULL
99 */
100void **
101GNUNET_xnew_array_2d_ (size_t n, size_t m, size_t elementSize)
102{
103 /* use char pointer internally to avoid void pointer arithmetic warnings */
104 char **ret = GNUNET_malloc (n * sizeof (void *) + /* 1. dim header */
105 n * m * elementSize); /* element data */
106
107 for (size_t i = 0; i < n; i++)
108 ret[i] = (char *)ret + /* base address */
109 n * sizeof (void *) + /* skip 1. dim header */
110 i * m * elementSize; /* skip to 2. dim row header */
111 return (void **)ret;
112}
113
114
115/**
116 * Allocate memory for a three dimensional array in one block
117 * and set up pointers. Aborts if no more memory is available.
118 * Don't use GNUNET_xnew_array_3d_ directly. Use the
119 * #GNUNET_new_array_3d macro.
120 * The memory of the elements will be zero'ed out.
121 *
122 * @param n size of the first dimension
123 * @param m size of the second dimension
124 * @param o size of the third dimension
125 * @param elementSize size of a single element in bytes
126 * @return allocated memory, never NULL
127 */
128void ***
129GNUNET_xnew_array_3d_ (size_t n, size_t m, size_t o, size_t elementSize)
130{
131 /* use char pointer internally to avoid void pointer arithmetic warnings */
132 char ***ret = GNUNET_malloc (n * sizeof (void **) + /* 1. dim header */
133 n * m * sizeof (void *) + /* 2. dim header */
134 n * m * o * elementSize); /* element data */
135
136 for (size_t i = 0; i < n; i++)
137 {
138 /* need to cast to (char *) temporarily for byte level acuracy */
139 ret[i] = (char **)((char *)ret + /* base address */
140 n * sizeof (void **) + /* skip 1. dim header */
141 i * m * sizeof (void *)); /* skip to 2. dim header */
142 for (size_t j = 0; j < m; j++)
143 ret[i][j] = (char *)ret + /* base address */
144 n * sizeof (void **) + /* skip 1. dim header */
145 n * m * sizeof (void *) + /* skip 2. dim header */
146 i * m * o * elementSize + /* skip to 2. dim part */
147 j * o * elementSize; /* skip to 3. dim row data */
148 }
149 return (void ***)ret;
150}
151
152
153/**
89 * Allocate and initialize memory. Checks the return value, aborts if no more 154 * Allocate and initialize memory. Checks the return value, aborts if no more
90 * memory is available. Don't use #GNUNET_xmemdup_() directly. Use the 155 * memory is available. Don't use #GNUNET_xmemdup_() directly. Use the
91 * GNUNET_memdup() macro. 156 * GNUNET_memdup() macro.
diff --git a/src/util/test_common_allocation.c b/src/util/test_common_allocation.c
index aa4809f58..4ef98b629 100644
--- a/src/util/test_common_allocation.c
+++ b/src/util/test_common_allocation.c
@@ -30,6 +30,8 @@ check ()
30{ 30{
31#define MAX_TESTVAL 1024 31#define MAX_TESTVAL 1024
32 char *ptrs[MAX_TESTVAL]; 32 char *ptrs[MAX_TESTVAL];
33 unsigned int **a2;
34 char ***a3;
33 int i; 35 int i;
34 int j; 36 int j;
35 int k; 37 int k;
@@ -93,6 +95,34 @@ check ()
93 if (ptrs[0] != NULL) 95 if (ptrs[0] != NULL)
94 return 9; 96 return 9;
95 97
98 /* GNUNET_new_array_2d tests */
99 a2 = GNUNET_new_array_2d (17, 22, unsigned int);
100 for (i = 0; i < 17; i++)
101 {
102 for (j = 0; j < 22; j++)
103 {
104 if (0 != a2[i][j])
105 return 10;
106 a2[i][j] = i * 100 + j;
107 }
108 }
109 free (a2);
110
111 /* GNUNET_new_array_3d tests */
112 a3 = GNUNET_new_array_3d (2, 3, 4, char);
113 for (i = 0; i < 2; i++)
114 {
115 for (j = 0; j < 3; j++)
116 {
117 for (k = 0; k < 4; k++)
118 {
119 if (0 != a3[i][j][k])
120 return 11;
121 a3[i][j][k] = i * 100 + j * 10 + k;
122 }
123 }
124 }
125 free (a3);
96 126
97 return 0; 127 return 0;
98} 128}