Skip to content

Instantly share code, notes, and snippets.

@interval1066
Created July 18, 2023 22:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save interval1066/527a2af67ff7f01428bcddff77ca1177 to your computer and use it in GitHub Desktop.
Save interval1066/527a2af67ff7f01428bcddff77ca1177 to your computer and use it in GitHub Desktop.
Constantly trying to find was to make things simpler here's a proposal for a pointer manager for C projects
#pragma once
#include <stdlib.h>
#include <stddef.h>
typedef struct
{
void (*print)(void*);
void (*destroy)(void*);
} BaseObject;
typedef struct
{
void** pointers;
size_t capacity;
size_t count;
} PointerManager;
void
pointer_manager_init(PointerManager* manager, size_t capacity) {
manager->pointers = calloc(capacity, sizeof(void*));
manager->capacity = capacity;
manager->count = 0;
}
void
pointer_manager_destroy(PointerManager* manager)
{
for (size_t i = 0; i < manager->count; ++i) {
if (manager->pointers[i] != NULL) {
BaseObject* obj = (BaseObject*)manager->pointers[i];
obj->destroy(manager->pointers[i]);
}
}
free(manager->pointers);
}
void*
pointer_manager_create(PointerManager* manager, void (*print)(void*), void (*destroy)(void*))
{
if (manager->count >= manager->capacity) {
return NULL; // Capacity reached, unable to create more pointers
}
BaseObject* obj = malloc(sizeof(BaseObject));
obj->print = print;
obj->destroy = destroy;
manager->pointers[manager->count++] = obj;
return obj;
}
void
pointer_manager_destroy_entry(PointerManager* manager, void* ptr)
{
for (size_t i = 0; i < manager->count; ++i) {
if (manager->pointers[i] == ptr) {
if (manager->pointers[i] != NULL) {
BaseObject* obj = (BaseObject*)manager->pointers[i];
obj->destroy(manager->pointers[i]);
}
manager->pointers[i] = NULL;
break;
}
}
}
Usage:
#include <stdio.h>
#include <stdlib.h>
#include "pmgr.h"
typedef struct
{
BaseObject base;
int value;
} ObjectA;
typedef struct
{
BaseObject base;
char data;
} ObjectB;
typedef struct
{
BaseObject base;
float number;
} ObjectC;
void objectA_print(void* obj)
{
ObjectA* objectA = (ObjectA*)obj;
printf("Object A - Value: %d\n", objectA->value);
}
void objectA_destroy(void* obj)
{
free(obj);
}
void objectB_print(void* obj)
{
ObjectB* objectB = (ObjectB*)obj;
printf("Object B - Data: %c\n", objectB->data);
}
void objectB_destroy(void* obj)
{
free(obj);
}
void objectC_print(void* obj)
{
ObjectC* objectC = (ObjectC*)obj;
printf("Object C - Number: %.2f\n", objectC->number);
}
void objectC_destroy(void* obj)
{
free(obj);
}
int main() {
PointerManager manager;
pointer_manager_init(&manager, 10);
// Example usage
ObjectA* objA = pointer_manager_create(&manager, objectA_print, objectA_destroy);
if (objA != NULL) {
objA->value = 42;
objA->base.print(objA);
}
ObjectB* objB = pointer_manager_create(&manager, objectB_print, objectB_destroy);
if (objB != NULL) {
objB->data = 'X';
objB->base.print(objB);
}
ObjectC* objC = pointer_manager_create(&manager, objectC_print, objectC_destroy);
if (objC != NULL) {
objC->number = 3.14f;
objC->base.print(objC);
}
pointer_manager_destroy_entry(&manager, objA);
pointer_manager_destroy_entry(&manager, objB);
pointer_manager_destroy_entry(&manager, objC);
pointer_manager_destroy(&manager);
return 0;
}
@interval1066
Copy link
Author

Recently on an embedded C project and the complexity was daunting, due in part to all the conscious pointer management the developer had to do. Here's my attempt to reign it in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment