aboutsummaryrefslogtreecommitdiff
path: root/src/util
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/util
parent939d0142629866734169ed7b2741aac7edd32cfc (diff)
downloadgnunet-2a6a2e9713184f13df1972ca3b10004f0bccd282.tar.gz
gnunet-2a6a2e9713184f13df1972ca3b10004f0bccd282.zip
gnunetutil: add 2d and 3d allocation including tests
Diffstat (limited to 'src/util')
-rw-r--r--src/util/common_allocation.c65
-rw-r--r--src/util/test_common_allocation.c30
2 files changed, 95 insertions, 0 deletions
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}