aboutsummaryrefslogtreecommitdiff
path: root/analyzer/utils/memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'analyzer/utils/memory.c')
-rw-r--r--analyzer/utils/memory.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/analyzer/utils/memory.c b/analyzer/utils/memory.c
new file mode 100644
index 0000000..91c5f18
--- /dev/null
+++ b/analyzer/utils/memory.c
@@ -0,0 +1,62 @@
+#include "memory.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+void *safe_malloc(size_t size) {
+ for (size_t i = 0; i < MAX_ALLOC_ATTEMPTS; i++) {
+ void *p = malloc(size);
+ if (p)
+ return p;
+ if (i < MAX_ALLOC_ATTEMPTS - 1) {
+ fprintf(stderr, "Failed malloc. Retrying in 1s...\n");
+ sleep(1);
+ }
+ }
+
+ fprintf(stderr, "FATAL: Failed malloc %d times. Exiting...", MAX_ALLOC_ATTEMPTS);
+ exit(EXIT_FAILURE);
+}
+
+void *safe_realloc(void *ptr, size_t size) {
+ if (!ptr)
+ return safe_malloc(size);
+
+ for (size_t i = 0; i < MAX_ALLOC_ATTEMPTS; i++) {
+ void *p = realloc(ptr, size);
+ if (p)
+ return p;
+ if (i < MAX_ALLOC_ATTEMPTS - 1) {
+ fprintf(stderr, "Failed realloc. Retrying in 1s...\n");
+ sleep(1);
+ }
+ }
+
+ fprintf(stderr, "FATAL: Failed realloc %d times. Exiting...", MAX_ALLOC_ATTEMPTS);
+ exit(EXIT_FAILURE);
+}
+
+// expand an array
+// returns pointer to the expanded array
+void *array_expand(void *arr, size_t el_size, size_t *cap, size_t to_fit) {
+ while (*cap < to_fit)
+ *cap *= 2;
+ return safe_realloc(arr, *cap * el_size);
+}
+
+void *array_append(void *arr, size_t el_size, size_t *len, size_t *cap, void *val) {
+ if (*len >= *cap)
+ arr = array_expand(arr, el_size, cap, *len + 1);
+ memcpy((char *)arr + (*len)++ * el_size, val, el_size);
+ return arr;
+}
+
+void *array_concat(void *arr1, size_t el_size, size_t *len1, size_t *cap, void *arr2, size_t len2) {
+ if (*len1 + len2 > *cap)
+ arr1 = array_expand(arr1, el_size, cap, *len1 + len2);
+ memcpy((char *)arr1 + *len1 * el_size, arr2, len2 * el_size);
+ *len1 += len2;
+ return arr1;
+}