New define in mem.c DEBUG_USE_AFTER_FREE_ON_WINDOWS which helps catch use-after-free issues in a debugger on Windows
diff --git a/src/mem.c b/src/mem.c
index 5022d26..57fda23 100644
--- a/src/mem.c
+++ b/src/mem.c
@@ -5,6 +5,13 @@
 
 #include <stdlib.h>
 
+// Enable this to catch use-after-free issues when debugging on Windows.
+// #define DEBUG_USE_AFTER_FREE_ON_WINDOWS
+
+#if !defined(DEBUG_USE_AFTER_FREE_ON_WINDOWS)
+
+// The standard implementation, using malloc() and free().
+
 void * avifAlloc(size_t size)
 {
     void * out = malloc(size);
@@ -18,3 +25,72 @@
 {
     free(p);
 }
+
+#else
+
+// This implementation rounds up all memory allocations to the nearest 4k (page size), allocates
+// using VirtualAlloc(), and then records the allocation in a linked list. When avifFree is called,
+// instead of freeing the memory, it simply revokes all read and write access to that region
+// forever. If any use-after-free issues are discovered (via fuzzing or the like), enabling this
+// should immediately catch it in a debugger right when it happens.
+
+#include <stdio.h>
+#include <windows.h>
+
+typedef struct Allocation
+{
+    void * ptr;
+    size_t originalSize;
+    size_t size;
+    struct Allocation * next;
+} Allocation;
+
+static Allocation * allocations = NULL;
+
+void * avifAlloc(size_t size)
+{
+    size_t originalSize = size;
+    size = (size + 4095) & ~(4095);
+
+    void * out = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
+    if (out == NULL) {
+        abort();
+    }
+
+    Allocation * a = (Allocation *)malloc(sizeof(Allocation));
+    a->ptr = out;
+    a->originalSize = originalSize;
+    a->size = size;
+    a->next = allocations;
+    allocations = a;
+
+    // printf("Alloc %p %zu (%zu)\n", a->ptr, a->originalSize, a->size);
+    return out;
+}
+
+void avifFree(void * p)
+{
+    if (!p) {
+        return;
+    }
+
+    Allocation * a = allocations;
+    for (; a != NULL; a = a->next) {
+        if (a->ptr == p) {
+            break;
+        }
+    }
+
+    if (!a) {
+        abort();
+    }
+
+    DWORD old;
+    if (!VirtualProtect(a->ptr, a->size, PAGE_NOACCESS, &old)) {
+        abort();
+    }
+
+    // printf("Free  %p %zu (%zu)\n", a->ptr, a->originalSize, a->size);
+}
+
+#endif