From ec7436a01deb8e28743de47ad98950c914d6da2a Mon Sep 17 00:00:00 2001
From: Christian C <cc@localhost>
Date: Tue, 1 Apr 2025 20:46:17 -0700
Subject: Global Allocator Checking

---
 lib/algo/avl_tree.c    |  9 +++++----
 lib/data/image_types.c | 47 ++++++++++++++++++++++++-----------------------
 lib/dir.c              |  8 +++++---
 lib/mem/galloc.c       | 29 +++++++++++++++++++++++++++++
 lib/seg/mask_data.c    |  5 +++--
 lib/seg/util.c         | 35 ++++++++++++++++++-----------------
 6 files changed, 84 insertions(+), 49 deletions(-)
 create mode 100644 lib/mem/galloc.c

(limited to 'lib')

diff --git a/lib/algo/avl_tree.c b/lib/algo/avl_tree.c
index cc06254..d8f887c 100644
--- a/lib/algo/avl_tree.c
+++ b/lib/algo/avl_tree.c
@@ -1,4 +1,5 @@
 #include <lib/algo/avl_tree.h>
+#include <lib/mem/galloc.h>
 #include <lib/monad.h>
 
 #include <stddef.h>
@@ -55,7 +56,7 @@ AVLNode *left_rotate(AVLNode *parent) {
 
 // Create AVL node
 AVLNode *create_avl_node(void *data, AvlComparator compare) {
-  AVLNode *node = (AVLNode *)malloc(sizeof(AVLNode));
+  AVLNode *node = (AVLNode *)g_malloc(sizeof(AVLNode));
   if (node == NULL) {
     return NULL;
   }
@@ -134,7 +135,7 @@ void free_avl_tree(AVLNode *root) {
   if (root != NULL) {
     free_avl_tree(root->left);
     free_avl_tree(root->right);
-    free(root);
+    g_free(root);
   }
 }
 
@@ -144,8 +145,8 @@ void free_avl_tree_nodes(AVLNode *root) {
     free_avl_tree_nodes(root->left);
     free_avl_tree_nodes(root->right);
     if (root->data != NULL) {
-      free(root->data);
+      g_free(root->data);
     }
-    free(root);
+    g_free(root);
   }
 }
diff --git a/lib/data/image_types.c b/lib/data/image_types.c
index 9a0e0ce..f5c9115 100644
--- a/lib/data/image_types.c
+++ b/lib/data/image_types.c
@@ -1,39 +1,40 @@
 #include <lib/data/image_types.h>
+#include <lib/mem/galloc.h>
 #include <stdio.h>
 #include <stdlib.h>
 
 Image *create_image(size_t width, size_t height, size_t channels) {
-  Image *ip = (Image *)malloc(sizeof(Image));
+  Image *ip = (Image *)g_malloc(sizeof(Image));
   if (ip == NULL) {
     return NULL;
   }
   ip->width = width;
   ip->height = height;
   ip->depth = channels;
-  ip->image = (ImageData_t ***)malloc(sizeof(ImageData_t **) * ip->height);
+  ip->image = (ImageData_t ***)g_malloc(sizeof(ImageData_t **) * ip->height);
   if (ip->image == NULL) {
     fprintf(stderr, "Memory allocation error\n");
-    free(ip);
+    g_free(ip);
     return NULL;
   }
   ImageData_t *image_data =
-      calloc(width * height * channels, sizeof(ImageData_t));
+      g_calloc(width * height * channels, sizeof(ImageData_t));
   if (image_data == NULL) {
     fprintf(stderr, "Memory allocation error\n");
-    free(ip->image);
-    free(ip);
+    g_free(ip->image);
+    g_free(ip);
     return NULL;
   }
   for (size_t y = 0; y < height; y++) {
-    ip->image[y] = (ImageData_t **)malloc(sizeof(ImageData_t *) * ip->width);
+    ip->image[y] = (ImageData_t **)g_malloc(sizeof(ImageData_t *) * ip->width);
     if (ip->image[y] == NULL) {
       fprintf(stderr, "Memory allocation error\n");
       for (size_t ty = 0; ty < y; ty++) {
-        free(ip->image[ty]);
+        g_free(ip->image[ty]);
       }
-      free(image_data);
-      free(ip->image);
-      free(ip);
+      g_free(image_data);
+      g_free(ip->image);
+      g_free(ip);
     }
     for (size_t x = 0; x < width; x++) {
       ip->image[y][x] = &image_data[(y * width + x) * channels];
@@ -43,21 +44,21 @@ Image *create_image(size_t width, size_t height, size_t channels) {
 }
 
 Mask *create_image_mask(size_t width, size_t height) {
-  Mask *ip = (Mask *)malloc(sizeof(Mask));
+  Mask *ip = (Mask *)g_malloc(sizeof(Mask));
   if (ip == NULL) {
     return NULL;
   }
   ip->width = width;
   ip->height = height;
-  ip->image = (MaskData_t **)malloc(sizeof(MaskData_t *) * ip->height);
+  ip->image = (MaskData_t **)g_malloc(sizeof(MaskData_t *) * ip->height);
   if (ip->image == NULL) {
-    free(ip);
+    g_free(ip);
     return NULL;
   }
-  MaskData_t *image_data = calloc(width * height, sizeof(MaskData_t));
+  MaskData_t *image_data = g_calloc(width * height, sizeof(MaskData_t));
   if (image_data == NULL) {
-    free(ip->image);
-    free(ip);
+    g_free(ip->image);
+    g_free(ip);
     return NULL;
   }
   for (size_t y = 0; y < height; y++) {
@@ -68,28 +69,28 @@ Mask *create_image_mask(size_t width, size_t height) {
 
 void free_image(Image *image) {
   if (image->image[0] != NULL) {
-    free(image->image[0]);
+    g_free(image->image[0]);
     image->image[0] = NULL;
   }
   if (image->image != NULL) {
-    free(image->image);
+    g_free(image->image);
     image->image = NULL;
   }
   if (image != NULL) {
-    free(image);
+    g_free(image);
   }
 }
 
 void free_image_mask(Mask *image_mask) {
   if (image_mask->image[0] != NULL) {
-    free(image_mask->image[0]);
+    g_free(image_mask->image[0]);
     image_mask->image[0] = NULL;
   }
   if (image_mask->image != NULL) {
-    free(image_mask->image);
+    g_free(image_mask->image);
     image_mask->image = NULL;
   }
   if (image_mask != NULL) {
-    free(image_mask);
+    g_free(image_mask);
   }
 }
diff --git a/lib/dir.c b/lib/dir.c
index 7200c52..361775d 100644
--- a/lib/dir.c
+++ b/lib/dir.c
@@ -1,5 +1,6 @@
 #include <dirent.h>
 #include <lib/dir.h>
+#include <lib/mem/galloc.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
@@ -20,7 +21,7 @@ char **list_directory(char *dirname) {
   DIR *d;
   struct dirent *dir;
   d = opendir(dirname);
-  char **file_names = (char **)malloc(sizeof(char *));
+  char **file_names = (char **)g_malloc(sizeof(char *));
   if (!file_names) {
     return NULL;
   }
@@ -33,7 +34,8 @@ char **list_directory(char *dirname) {
         /// Create space for it in the list
         file_names = realloc(file_names, (file_count + 1 + 1) * sizeof(char *));
         /// Create space for the name
-        file_names[file_count] = calloc(strlen(dir->d_name) + 1, sizeof(char));
+        file_names[file_count] =
+            g_calloc(strlen(dir->d_name) + 1, sizeof(char));
         /// Copy the name
         strcpy(file_names[file_count], dir->d_name);
         /// Mark the end of the file list with a NULL entry
@@ -50,7 +52,7 @@ char *full_path(char *dir, char *file) {
   char *fpath = NULL;
   size_t dir_len = strlen(dir);
   size_t file_len = strlen(file);
-  fpath = (char *)calloc(dir_len + file_len + 2, sizeof(char));
+  fpath = (char *)g_calloc(dir_len + file_len + 2, sizeof(char));
   strcpy(fpath, dir);
   strcpy(fpath + dir_len + 1, file);
   fpath[dir_len] = '/';
diff --git a/lib/mem/galloc.c b/lib/mem/galloc.c
new file mode 100644
index 0000000..642e010
--- /dev/null
+++ b/lib/mem/galloc.c
@@ -0,0 +1,29 @@
+#include <lib/mem/galloc.h>
+#include <stdlib.h>
+
+static ssize_t standing_allocations = 0;
+
+void *g_malloc(size_t size) {
+  void *ptr = malloc(size);
+  if (ptr == NULL) {
+    return ptr;
+  }
+  standing_allocations++;
+  return ptr;
+}
+
+void *g_calloc(size_t n_memb, size_t size) {
+  void *ptr = calloc(n_memb, size);
+  if (ptr == NULL) {
+    return ptr;
+  }
+  standing_allocations++;
+  return ptr;
+}
+
+void g_free(void *ptr) {
+  free(ptr);
+  standing_allocations--;
+}
+
+ssize_t g_outstanding_allocations() { return standing_allocations; }
diff --git a/lib/seg/mask_data.c b/lib/seg/mask_data.c
index 144c7ca..5789f08 100644
--- a/lib/seg/mask_data.c
+++ b/lib/seg/mask_data.c
@@ -1,3 +1,4 @@
+#include <lib/mem/galloc.h>
 #include <lib/seg/mask_data.h>
 #include <lib/seg/util.h>
 
@@ -5,7 +6,7 @@
 
 // Allocate Mask Data for Label
 MaskData *create_mask_data(MaskData_t label) {
-  MaskData *data = (MaskData *)malloc(sizeof(MaskData));
+  MaskData *data = (MaskData *)g_malloc(sizeof(MaskData));
   data->label = label;
   data->area = 0;
   data->perimeter = 0;
@@ -33,7 +34,7 @@ AVLNode *insert_mask_alloc(AVLNode *node, MaskData_t label) {
   MaskData *data = create_mask_data(label);
   Result result = insert_mask(node, data);
   if (!result.success) {
-    free(data);
+    g_free(data);
   }
   return (AVLNode *)result.data;
 }
diff --git a/lib/seg/util.c b/lib/seg/util.c
index 8af8199..a9db067 100644
--- a/lib/seg/util.c
+++ b/lib/seg/util.c
@@ -1,5 +1,6 @@
 #include <assert.h>
 #include <lib/algo/flood_fill.h>
+#include <lib/mem/galloc.h>
 #include <lib/png.h>
 #include <lib/seg/util.h>
 #include <stdio.h>
@@ -80,8 +81,8 @@ MaskData_t *_dilate(const Mask *mask) {
     }
   }
   MaskData_t *ret_mask = new_mask->image[0];
-  free(new_mask->image);
-  free(new_mask);
+  g_free(new_mask->image);
+  g_free(new_mask);
   return ret_mask;
 }
 
@@ -89,7 +90,7 @@ MaskData_t *_dilate(const Mask *mask) {
 void dilate(Mask *mask) {
   MaskData_t *new_mask = _dilate(mask);
   if (new_mask != NULL) {
-    free(mask->image[0]);
+    g_free(mask->image[0]);
     for (size_t y = 0; y < mask->height; y++) {
       mask->image[y] = &(new_mask[y * mask->width]);
     }
@@ -132,8 +133,8 @@ MaskData_t *_erode(const Mask *mask) {
     }
   }
   MaskData_t *ret_mask = new_mask->image[0];
-  free(new_mask->image);
-  free(new_mask);
+  g_free(new_mask->image);
+  g_free(new_mask);
   return ret_mask;
 }
 
@@ -141,7 +142,7 @@ MaskData_t *_erode(const Mask *mask) {
 void erode(Mask *mask) {
   MaskData_t *new_mask = _erode(mask);
   if (new_mask != NULL) {
-    free(mask->image[0]);
+    g_free(mask->image[0]);
     for (size_t y = 0; y < mask->height; y++) {
       mask->image[y] = &(new_mask[y * mask->width]);
     }
@@ -169,8 +170,8 @@ MaskData_t *_closeup(Mask *mask, size_t num_pixels) {
     }
   }
   MaskData_t *ret_mask = new_mask->image[0];
-  free(new_mask->image);
-  free(new_mask);
+  g_free(new_mask->image);
+  g_free(new_mask);
   return ret_mask;
 }
 
@@ -179,7 +180,7 @@ MaskData_t *_closeup(Mask *mask, size_t num_pixels) {
 void closeup(Mask *mask, size_t num_pixels) {
   MaskData_t *new_mask = _closeup(mask, num_pixels);
   if (new_mask != NULL) {
-    free(mask->image[0]);
+    g_free(mask->image[0]);
     for (size_t y = 0; y < mask->height; y++) {
       mask->image[y] = &(new_mask[y * mask->width]);
     }
@@ -227,7 +228,7 @@ Mask *tif_to_labels(char *tif_file_name, MaskData_t *starting_label_p) {
   channels = (STRIP_LENGTH * STRIP_COUNT) / (width * height);
 
   //-TIFF-LOAD-DATA--------------------------------
-  void *buffer = malloc(STRIP_LENGTH * sizeof(ImageData_t));
+  void *buffer = g_malloc(STRIP_LENGTH * sizeof(ImageData_t));
   if (buffer == NULL) {
     fprintf(stderr, "Memory allocation error\n");
     TIFFClose(tif);
@@ -236,7 +237,7 @@ Mask *tif_to_labels(char *tif_file_name, MaskData_t *starting_label_p) {
   Image *image = create_image(width, height, channels);
   if (image == NULL) {
     fprintf(stderr, "Memory allocation error\n");
-    free(buffer);
+    g_free(buffer);
     TIFFClose(tif);
     return NULL;
   }
@@ -247,7 +248,7 @@ Mask *tif_to_labels(char *tif_file_name, MaskData_t *starting_label_p) {
       image->image[0][0][x + y * STRIP_LENGTH] = ((ImageData_t *)buffer)[x];
     }
   }
-  free(buffer);
+  g_free(buffer);
 
   //-FLOOD-FILL-SEGMENTATION-----------------------
   //-CONTIGUOUS-REGION-FINDING---------------------
@@ -279,13 +280,13 @@ Bitmap *image_mask_data_to_bitmap(const Mask *mask) {
   MaskData_t *buffer = mask->image[0];
   uint32_t width = mask->width;
   uint32_t height = mask->height;
-  Pixel *out_buffer = (Pixel *)calloc(width * height, sizeof(Pixel));
+  Pixel *out_buffer = (Pixel *)g_calloc(width * height, sizeof(Pixel));
   if (out_buffer == NULL) {
     return NULL;
   }
-  Bitmap *bitmap = (Bitmap *)malloc(sizeof(Bitmap));
+  Bitmap *bitmap = (Bitmap *)g_malloc(sizeof(Bitmap));
   if (bitmap == NULL) {
-    free(out_buffer);
+    g_free(out_buffer);
     return NULL;
   }
   for (size_t y = 0; y < height; y++) {
@@ -311,7 +312,7 @@ MaskData_t *_reduce_contiguous_regions(MaskData_t *masks, uint32_t width,
                                        MaskData_t *total_labels) {
   MaskData_t starting_label = 1;
   MaskData_t *new_masks =
-      (MaskData_t *)calloc(width * height, sizeof(MaskData_t));
+      (MaskData_t *)g_calloc(width * height, sizeof(MaskData_t));
   if (new_masks == NULL) {
     return NULL;
   }
@@ -341,7 +342,7 @@ void reduce_contiguous_regions(Mask *mask, MaskData_t *total_labels) {
   MaskData_t *new_masks = _reduce_contiguous_regions(
       mask->image[0], mask->width, mask->height, total_labels);
   if (new_masks != NULL) {
-    free(mask->image[0]);
+    g_free(mask->image[0]);
     for (size_t y = 0; y < mask->height; y++) {
       mask->image[y] = &new_masks[y * mask->width];
     }
-- 
cgit v1.2.1