You are not logged in.

#1 2009-07-20 23:00:35

vkumar
Member
Registered: 2008-10-06
Posts: 166

non-realtime automated garbage collection for C

All this does is keep track of everything you alloc on the heap, and when main returns (or your program exits), it cleans everything up.
("non-realtime" is just another way of saying "very lazy".)

It's useful when you're creating many objects on the heap and storing them within other structures - because you no longer have to worry about freeing memory.

Also, when you've got a ton of stuff on the heap and your program suddenly needs to exit - everything is de-allocated properly (without any hassle).

You can use *alloc/free alongside kgc functions without any side-effects.
If you compile this with "THREAD_SAFE_KGC" #define'd, it will make allocations thread safe.

/*
 * kgc.h
 * Copyright (c) 2009 Vedant Kumar
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#pragma once

#include <stdlib.h>

#define THREAD_SAFE_KGC
#ifdef THREAD_SAFE_KGC
    #include <semaphore.h>
    sem_t __kgc__mutex;
#endif

static void** __kgc__mem_ptrs;
static unsigned long __kgc__cur, __kgc__max;

static void __clear_mem__() {
    for (__kgc__max=0; __kgc__max < __kgc__cur; ++__kgc__max) {
        free(__kgc__mem_ptrs[__kgc__max]);
    }

    free(__kgc__mem_ptrs);

#ifdef THREAD_SAFE_KGC
    sem_destroy(&__kgc__mutex);
#endif
}

void kgc_init() {
    __kgc__cur = 0;
    __kgc__max = 2 << 10;
    __kgc__mem_ptrs = malloc(sizeof(void*) * __kgc__max);
    atexit(__clear_mem__);

#ifdef THREAD_SAFE_KGC
    sem_init(&__kgc__mutex, 0, 1);
#endif
}

static char __add_ptr__(void* ptr) {
#ifdef THREAD_SAFE_KGC
    sem_wait(&__kgc__mutex);
#endif

    if (__kgc__cur < __kgc__max) {
        __kgc__mem_ptrs[__kgc__cur++] = ptr;
#ifdef THREAD_SAFE_KGC
        sem_post(&__kgc__mutex);
#endif
        return 'a';
    } else {
        __kgc__max *= 4;

        void** temp = realloc(__kgc__mem_ptrs, __kgc__max);
        if (temp != NULL) {
            __kgc__mem_ptrs = temp;
            __kgc__mem_ptrs[__kgc__cur++] = ptr;
            return 'a';
#ifdef THREAD_SAFE_KGC
            sem_post(&__kgc__mutex);
#endif
        } else {
#ifdef THREAD_SAFE_KGC
            sem_post(&__kgc__mutex);
#endif
            return 'f';
        }
    }

    return 's';
}

#define __ptr_handler__(p) \
    if (p == NULL) { \
        return NULL; \
    } \
    switch (__add_ptr__(p)) { \
        case 'a': \
            return p; \
        case 'f': \
            return NULL; \
        case 's': \
            exit(-1); \
    } \
    return p; \

void* kgc_malloc(unsigned long size) {
    void* p = malloc(size);
    __ptr_handler__(p);
}

void* kgc_realloc(void* src, unsigned long size) {
    void* p = realloc(src, size);
    __ptr_handler__(p);
}

void* kgc_calloc(unsigned long num, unsigned long size) {
    void* p = calloc(num, size);
    __ptr_handler__(p);
}

#define new(type) (type*) kgc_malloc(sizeof(type))

(final?) edit:
ok, I think it's all done! I should get an award for most obfuscated code, or something..

here's the API:

kgc_init() // call this in main as early as possible
kgc_malloc(sz)
kgc_calloc(num, sz)
kgc_realloc(src, sz)

new(type) // a macro that behaves like C++'s 'new', without the support for arrays
// e.g: int* x = new(int);

enjoy

Last edited by vkumar (2009-07-21 03:18:27)


div curl F = 0

Offline

#2 2009-07-20 23:07:30

benob
Member
Registered: 2008-11-11
Posts: 187

Re: non-realtime automated garbage collection for C

One question: why do you need to free() at all? Isn't that done implicitly when your program exits?

Offline

#3 2009-07-21 00:58:35

vkumar
Member
Registered: 2008-10-06
Posts: 166

Re: non-realtime automated garbage collection for C

edit:
I suppose Dimigon is right about this, disregard the earlier post.

By the way, there's an unwanted feature (read 'bug') in the first version of my post.
'++cur' was supposed to be 'cur++'.. fixing..

Last edited by vkumar (2009-07-21 16:54:59)


div curl F = 0

Offline

#4 2009-07-21 07:53:33

dimigon
Member
Registered: 2009-03-07
Posts: 139
Website

Re: non-realtime automated garbage collection for C

In user space memory leaks can only happen during program execution. When a program terminates all the memory that it has allocated during its lifetime is reclaimed by the operating system. The GNU coding manual suggests that it is not necessary to bother freeing stuff upon termination. Nevertheless it is a good practice so as to avoid false positives by valgrind or similar software. For easier memory management in some situations look into http://www.gnu.org/software/hello/manua … tacks.html. Memory should be freed during program execution whenever it is not to be referenced again. And that is the job of a real-time garbage collector or any competent programmer.

Last edited by dimigon (2009-07-21 10:24:10)

Offline

#5 2009-07-21 17:04:46

vkumar
Member
Registered: 2008-10-06
Posts: 166

Re: non-realtime automated garbage collection for C

Memory should be freed during program execution whenever it is not to be referenced again. And that is the job of a real-time garbage collector or any competent programmer.

I agree, and I wouldn't use the code I posted for any serious application. It's not intended to replace other garbage collectors - I thought it was an interesting exercise.

All I intended it to do was catch basic mistakes, like memory leaks, with a simple interface. For example, if someone ran this code (not that they should!), it would free the memory a originally pointed to.

char* a = (char*) kgc_ malloc(32);
char* b = (char*) kgc_malloc(64);
a = b;

Last edited by vkumar (2009-07-21 17:19:49)


div curl F = 0

Offline

#6 2009-07-21 21:31:39

dimigon
Member
Registered: 2009-03-07
Posts: 139
Website

Re: non-realtime automated garbage collection for C

vkumar wrote:

Memory should be freed during program execution whenever it is not to be referenced again. And that is the job of a real-time garbage collector or any competent programmer.

I agree, and I wouldn't use the code I posted for any serious application. It's not intended to replace other garbage collectors - I thought it was an interesting exercise.

All I intended it to do was catch basic mistakes, like memory leaks, with a simple interface. For example, if someone ran this code (not that they should!), it would free the memory a originally pointed to.

char* a = (char*) kgc_ malloc(32);
char* b = (char*) kgc_malloc(64);
a = b;

I agree that your interface would free the memory, however you still don't save yourself from memory leaks since you tackle the problem upon termination and memory leaks can only occur during program execution.

It is always advised to experiment with ideas. The good thing is that whenever a really genuine idea arises you will at least have the technical skills to tackle the problem in some way.

Last edited by dimigon (2009-07-21 21:36:18)

Offline

#7 2009-07-24 17:06:27

vkumar
Member
Registered: 2008-10-06
Posts: 166

Re: non-realtime automated garbage collection for C

I agree that your interface would free the memory, however you still don't save yourself from memory leaks since you tackle the problem upon termination and memory leaks can only occur during program execution.

I feel so stupid.. I now realize that each process gets its own heap!
I used to think that the 'heap' meant all of your computer memory..


div curl F = 0

Offline

Board footer

Powered by FluxBB