diff options
author | Markus Teich <teichm@fs.tum.de> | 2016-09-07 22:31:05 +0000 |
---|---|---|
committer | Markus Teich <teichm@fs.tum.de> | 2016-09-07 22:31:05 +0000 |
commit | 2a6a2e9713184f13df1972ca3b10004f0bccd282 (patch) | |
tree | 596a07b4b281eeffc8d0293b8e932ff48b593351 /src | |
parent | 939d0142629866734169ed7b2741aac7edd32cfc (diff) | |
download | gnunet-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.h | 56 | ||||
-rw-r--r-- | src/util/common_allocation.c | 65 | ||||
-rw-r--r-- | src/util/test_common_allocation.c | 30 |
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 | */ | ||
1005 | void ** | ||
1006 | GNUNET_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 | */ | ||
1022 | void *** | ||
1023 | GNUNET_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 | */ | ||
100 | void ** | ||
101 | GNUNET_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 | */ | ||
128 | void *** | ||
129 | GNUNET_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 | } |