The idea is to init garbage heap in the beginning of main
, use gmalloc
, gcalloc
and grealloc
wrappers and free all allocated memory in the end of main. It helps to avoid memory leaks when writing programs for ejudge systems. Would like to hear general feedback on the idea and advices on how to improve the code (beginner in C).
main.c
/*
Example of usage of garbage heap.
No free() call but no memory leak.
*/
#include "garbage_heap.h"
int main() {
init_garbage_heap();
for (int i = 0; i < 1000; ++i)
{
char* str = gmalloc(1000*sizeof(char));
str = grealloc(str, 2000*sizeof(char));
}
free_garbage_heap();
return 0;
}
garbage_heap.h
#ifndef GARBAGE_HEAP_H
#define GARBAGE_HEAP_H
#include <stddef.h>
void init_garbage_heap (void);
void free_garbage_heap (void);
void* gmalloc (size_t sizemem);
void* gcalloc (size_t number, size_t size);
void* grealloc (void* ptrmem, size_t sizemem);
#endif // GARBAGE_HEAP_H
garbage_heap.c
#include <stdlib.h>
#include "garbage_heap.h"
typedef struct
{
void** buffer;
int len;
int capacity;
}
GarbageHeap;
static GarbageHeap garbage_heap;
void init_garbage_heap(void)
{
int len = 32;
garbage_heap.len = 0;
garbage_heap.capacity = len;
garbage_heap.buffer = (void**)malloc(sizeof(void*)*len);
for (int i = 0; i < len; ++i)
garbage_heap.buffer[i] = NULL;
}
void free_garbage_heap(void)
{
for (int i = 0; i < garbage_heap.len; ++i)
if (garbage_heap.buffer[i] != NULL)
free(garbage_heap.buffer[i]);
free(garbage_heap.buffer);
}
void resize_garbage_heap(void)
{
garbage_heap.capacity *= 2;
garbage_heap.buffer = (void**)realloc(garbage_heap.buffer, sizeof(void*) * garbage_heap.capacity);
for (int i = garbage_heap.len; i < garbage_heap.capacity; ++i)
garbage_heap.buffer[i] = NULL;
}
void* gmalloc(size_t sizemem)
{
if (garbage_heap.len == garbage_heap.capacity)
resize_garbage_heap();
garbage_heap.buffer[garbage_heap.len] = malloc(sizemem);
++garbage_heap.len;
return garbage_heap.buffer[garbage_heap.len - 1];
}
void* gcalloc(size_t number, size_t size)
{
if (garbage_heap.len == garbage_heap.capacity)
resize_garbage_heap();
garbage_heap.buffer[garbage_heap.len] = calloc(number, size);
++garbage_heap.len;
return garbage_heap.buffer[garbage_heap.len - 1];
}
void* grealloc(void* ptrmem, size_t sizemem)
{
if (ptrmem == NULL)
return gmalloc(sizemem);
int i = 0;
while (garbage_heap.buffer[i] != ptrmem)
++i;
void* tmp_ptr = realloc(ptrmem, sizemem);
if (tmp_ptr != NULL)
garbage_heap.buffer[i] = tmp_ptr;
return tmp_ptr;
}