A lightweight garbage collection library for C that automatically tracks allocated memory and provides functions to manage memory cleanup.
- No global variables: Context managed internally with function-scope static variable
- Automatic memory tracking: All allocations made with
gc_malloc()are automatically tracked - Simple API: No need to pass context - just call
gc_init()once and usegc_malloc() - Individual pointer freeing: Free specific pointers with
gc_free() - Bulk cleanup: Free all tracked pointers at once with
gc_clean() - Memory statistics: Check how many pointers are currently tracked with
gc_count() - Custom realloc: No dependency on standard
realloc(), uses custom implementation - Modular design: Each function in its own file for better maintainability
Initialize the garbage collector.
- Returns: 0 on success, -1 on failure
- Note: Must be called once before using any other gc functions
Allocate memory and track the pointer for garbage collection.
- Parameters:
size- Size of memory to allocate in bytes
- Returns: Pointer to allocated memory, or NULL on failure
Free a specific tracked pointer.
- Parameters:
ptr- Pointer to free (must have been allocated withgc_malloc)
- Returns: 0 on success, -1 if pointer not found or not tracked
Free all tracked pointers and cleanup the garbage collector.
- Note: Resets the internal context to NULL
Get the number of currently tracked pointers.
- Returns: Number of tracked pointers
#include "libgc.h"
#include <stdio.h>
#include <string.h>
int main(void) {
// Initialize the garbage collector (call once)
if (gc_init() != 0) {
printf("Failed to initialize garbage collector\n");
return 1;
}
// Allocate memory (automatically tracked, no context needed!)
char *str1 = gc_malloc(100);
char *str2 = gc_malloc(50);
int *numbers = gc_malloc(sizeof(int) * 10);
// Use the allocated memory
strcpy(str1, "Hello, libgc!");
strcpy(str2, "Another string");
for (int i = 0; i < 10; i++) {
numbers[i] = i * i;
}
printf("Currently tracking %zu pointers\n", gc_count());
// Free a specific pointer
gc_free(str2);
printf("After freeing str2: %zu pointers\n", gc_count());
// Clean up all remaining pointers
gc_clean();
printf("After cleanup: %zu pointers\n", gc_count());
return 0;
}See usage example above - typical flow:
gc_init() → gc_malloc(size) → [use memory] → gc_free(ptr)/gc_clean()Key test scenarios:
- Allocation failure handling (check NULL returns)
- Resize behavior (allocate >16 pointers to trigger growth)
- Untracking non-existent pointers (should return -1)
- Double cleanup (gc_clean should be safe when already cleaned)
To use libgc in your project:
# Compile your program
cc -o myprogram myprogram.c -lgc
# Or if not installed system-wide
cc -o myprogram myprogram.c -L/path/to/libgc -lgc- Call
gc_init()once at the start of your program - Replace
malloc()withgc_malloc()- that's it! - Call
gc_clean()before program exit to free all tracked memory - Don't mix regular
malloc()/free()withgc_malloc()/gc_free()for the same pointers - Don't call
gc_free()on pointers not allocated withgc_malloc()
- Single-threaded: Not thread-safe (would need additional synchronization for multi-threaded use)
- No circular reference detection: Simple tracking, not a full garbage collector
- Memory overhead: Small overhead for tracking each pointer
- No automatic collection: Memory is only freed when explicitly requested
- Functions return appropriate error codes (-1 for failure, 0 for success)
gc_malloc()returns NULL on allocation failuregc_free()returns -1 if the pointer is not tracked- Always check return values for proper error handling