Skip to content

Kolbxyz/My_STL

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Garbage Collector Documentation

This document provides a detailed explanation of a simple garbage collector implemented in C. The garbage collector uses a combination of macros and the __attribute__((cleanup(...))) GCC extension to automatically manage memory for different data types, including raw pointers, vectors (dynamic arrays), strings, and file descriptors.

Core Concepts

Smart Pointers & Automatic Cleanup

The core of the system is the "smart pointer" concept. By using the __attribute__((cleanup(func))) attribute, a variable can be associated with a specific cleanup function that is automatically called when the variable goes out of scope. This ensures that resources (memory, file handles) are released without manual intervention.

The _C(func) macro is a shorthand for this attribute.

Metadata Header (ptr_header_t)

Every memory block managed by this garbage collector is preceded by a ptr_header_t struct. This header stores vital metadata about the allocation.

typedef struct s_ptr_header {
    unsigned int magic; // Must be 0xDEADBEEF
    const char *type;
    const char *file;
    int refs;
    int line;
    size_t size;
    size_t capacity;
} ptr_header_t;
  • magic: A constant value (0xDEADBEEF) to verify that a pointer is indeed managed by this GC.
  • type: A string representing the data type (e.g., "char *").
  • file, line: The source file and line number where the pointer was created, for debugging.
  • refs: A reference counter for shared ownership.
  • size: The number of elements in the allocation (for vectors) or bytes.
  • capacity: The total allocated capacity in bytes (for vectors).

The GET_HDR(p) macro is used to retrieve the header from a given user-facing pointer.

Smart Pointer Macros

These macros are the primary way to interact with the garbage collector.

General Purpose

  • OWN(n, t, e): Creates an owned smart pointer. This is the most common macro.

    • n: The name of the variable.
    • t: The type of the variable.
    • e: The expression that provides the initial pointer (e.g., malloc(...), strdup(...)).
    • Cleanup: The associated memory is freed when the variable goes out of scope.
  • SHARE(n, t, p): Creates a shared smart pointer from an existing smart pointer p.

    • This increments the reference count (refs) in the pointer's header.
    • Cleanup: The reference count is decremented. The memory is only freed when the count reaches zero.

Specialized Macros

  • STRING(name, s): A convenient wrapper around OWN for creating a managed string. It uses strdup internally.
  • FOPEN(name, p, m): Wraps a FILE * from fopen.
    • Cleanup: Automatically calls fclose.
  • OPEN(n, path, flags): Wraps an integer file descriptor from open.
    • Cleanup: Automatically calls close.

Vector (Dynamic Array) Library

The garbage collector includes a fully-featured, type-safe dynamic array (vector) implementation. A vector created with this system will automatically grow as needed and will be freed when it goes out of scope.

Vector Creation

Vectors are created like any other smart pointer, typically by initializing an OWN variable to NULL.

OWN(my_vector, int *, NULL); // Creates an empty vector of integers

Vector Operations

  • APPEND(vec, val, t): Appends a value val of type t to the end of the vector vec. The vector grows automatically if its capacity is exceeded.
  • REMOVE(vec, idx, t): Removes the element at idx of type t from the vector.
  • LEN(v): Returns the number of elements currently in the vector.
  • CAP(v): Returns the total capacity of the vector.
  • FOREACH(i, arr): A convenience macro for iterating over a vector from index 0 to LEN(arr) - 1.
  • MAP(arr, func): Applies a function func to each element of the vector.

Core Functions

These are the underlying functions that power the macro-based API.

  • void *gc_init(void *raw_ptr, const char *type, char *file, int line): Initializes the metadata header for a new smart pointer.
  • void *gc_share(void *raw_ptr): Handles the logic for creating a shared pointer (increments reference count).
  • void gc_cleanup(void *p): The main cleanup function for OWN pointers. It decrements the reference count and frees the memory if the count is zero.
  • void *gc_append_vec(void *arr, void *item, size_t item_size): The function behind the APPEND macro.
  • void gc_remove_vec(void *arr, size_t index, size_t item_size): The function behind the REMOVE macro.
  • void gc_map_vec(void *arr, int (*func)(int)): The function behind the MAP macro.
  • void gc_map_string(void *arr, char (*func)(char)): The function behind the SMAP macro.
  • char *smart_read(FILE *stream): Reads an entire file stream into a new, managed string.
  • gc_f_arr, gc_f_file, gc_close_fd: Specialized cleanup functions for arrays of pointers, FILE*, and file descriptors, respectively.

Example Usage

#include "gc.h"
#include <stdio.h>

int main(void)
{
    // 1. Owned string
    STRING(message, "Hello from the garbage collector!");
    printf("Message: %s\n", message);

    // 2. Vector (dynamic array) of integers
    OWN(my_vector, int *, NULL); // Initialize as NULL
    for (int i = 0; i < 5; ++i) {
        APPEND(my_vector, i * 10, int);
    }

    printf("Vector (len=%zu, cap=%zu): ", LEN(my_vector), CAP(my_vector));
    FOREACH(i, my_vector) {
        printf("%d ", my_vector[i]);
    }
    printf("\n");

    REMOVE(my_vector, 2, int); // Remove the 3rd element (20)
    printf("After removing element at index 2: ");
    FOREACH(i, my_vector) {
        printf("%d ", my_vector[i]);
    }
    printf("\n");

    // 3. File handling
    FOPEN(my_file, "example.txt", "w+");
    if (my_file) {
        fprintf(my_file, "This is a test file.\n");
        rewind(my_file);
        STRING(content, smart_read(my_file));
        printf("File content: %s", content);
    }

    // 4. Shared Pointers
    OWN(original_ptr, int *, malloc(sizeof(int)));
    *original_ptr = 123;

    {
        SHARE(shared_ptr, int *, original_ptr); // Create a shared reference
        printf("Value from shared pointer: %d\n", *shared_ptr);
        // 'shared_ptr' goes out of scope, ref count decremented
    }

    printf("Value from original pointer: %d\n", *original_ptr);

    return 0;
}
// All variables created with OWN, STRING, FOPEN, etc. are automatically
// cleaned up here as they go out of scope.

About

Simple garbage collector & basic STL functions implemented in C.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors