Standard garbage collector:
Code:
/* this code has not been compiled. use at your own risk */
struct _memory {
void ** marshal, * pointer;
} memory;
void init(memory * m)
{
m->pointer = 0;
m->marshal = &m->pointer;
}
int track(memory * m, void ** pointer)
/* returns 1 on success, 0 if the memory is still tied up */
{
if(collect(m)) {
m->marhal = pointer;
m->pointer = *pointer;
} else return 0;
return 1;
}
int collect(memory * m)
/* returns 1 on success, even if no collection was necessary,
0 if the memory is still tied up */
{
if(collectable(m))free(m->pointer), m->marshal = &m->pointer;
else return 0;
return 1;
}
int collectable(memory * m)
/* returns 1 if the memory is invalid, 0 if still good */
{
if(m->pointer != *m->marshal // trash
|| m->marshal == &m->pointer) // neutral
return 1;
return 0;
}
int alloc(memory * m, void ** pointer, unsigned amount)
/* returns number of bytes allocated on success,
0 on bad alloc, -1 if the memory is still tied up */
{
*pointer = malloc(amount);
if(!*pointer)
return 0;
if(!track(m, pointer))
return -1;
return amount;
}
int main()
{
const int size = 10240;
memory monitor, * m = &monitor;
char * buffer = 0;
init(m);
alloc(m, &buffer, size); // ignore result for now.
buffer = "- memory leak?";
collect(m);
}
Store the structures in a linked list or similar.
Launching the process in its own, low priority thread would be a good idea, too.
Naturally, C++ would better suited for this task, IMHO;