Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

New Cancer - Femgineers

Name: Anonymous 2012-06-08 14:20

Name: Anonymous 2012-06-12 15:47

I wrote my own C heap allocator. It probably doesn't compile because I didn't try to compile it or even briefly check for syntax errors, and even when it does compile it probably won't work without some [b][i][o][u]REFACTORING[/i][/o][/i][/b] but I'm not submitting this as an attempt to win a degree, so here it is:

heapofshit.h
#ifndef HEAP_OF_SHIT_H
#define HEAP_OF_SHIT_H

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
# ifndef WINDOWS
#  define WINDOWS
# endif
#elif defined(POSIX) || defined(__POSIX__) || defined(unix) || defined(__unix__)
# ifndef POSIX
#  define POSIX
# endif
#endif

/**
 * \brief    Allocates a block of shit.
 * \param size    The size of the shit-block in bytes.
 * \return    On success, a pointer to the shit-block is returned. On error,
 *        NULL is returned and errno is set to indicate the error that
 *        occurred.
 */
void* take_shit(size_t size);

/**
 * \brief    Allocates a block of shit and sets every
 * \param count    The number of elements in the shit-block.
 * \param size    The size in bytes of each shit-element.
 * \return    On success, a pointer to the shit-block is returned. On error,
 *        NULL is returned and errno is set to indicate the error that
 *        occurred.
 */
void* ztake_shit(size_t count, size_t size);

/**
 * \brief    Resizes a block of shit.
 * \param shit    A pointer to the shit-block to be resized.
 * \param new_size The new size of the shit-block.
 * \return    On success, the resized shit-block is returned. On error, NULL
 *        is returned and errno is set to indicate the error that
 *        occurred.
 */
void* resize_shit(void* shit, size_t new_size);

/**
 * \brief    Flushes a block of shit.
 * \param shit    The shit-block to flush. If this is a null pointer, no action is
 *        performed.
 * \return    This function does not return a value.
 */
void flush_shit(void* shit);

#endif /* ! HEAP_OF_SHIT_H */


heapofshit.c
#include <heapofshit.h>

#if defined(WINDOWS)
# include <Windows.h>
#elif defined(POSIX)
# include <unistd.h>
#endif

#ifdef POSIX
/** Stores shit-blocks. */
static struct shitblock {
    void*    start;    /**< The start of the shit-block. */
    size_t    size;    /**< The size of the shit-block. */
    int    used;    /**< Whether the shit-block is in use. */
} * shitblocklist;    /**< The list of shit-blocks. */
size_t num_shitblocks;    /**< The number of shit-blocks in the list. */
ssize_t next_free = -1;    /**< Index of the next free block. */
#endif

/**
 * \brief    Allocates a block of shit.
 * \param size    The size of the shit-block in bytes.
 * \return    On success, a pointer to the shit-block is returned. On error,
 *        NULL is returned.
 */
void* take_shit(size_t size)
{
#if defined(WINDOWS)
    return HeapAlloc(GetProcessHeap(), 0, size);
#elif defined(POSIX)
    if (!(shitblocklist)) {
        /* Initialise the shit-block list.
         */
        shitblocklist = sbrk(sizeof(*shitblocklist) * (num_shitblocks + 1));
        shitblocklist[0].start = sbrk(size);
        shitblocklist[0].size  = size;
        shitblocklist[0].used  = 1;
        ++num_shitblocks;
        return shitblocklist[0].start;
    } else if ((next_free >= 0) && (size <= shitblocklist[next_free].size)) {
        /* Use the next free block if it's big enough.
         */
        void* p = shitblocklist[next_free].start;
        shitblocklist[next_free].used = 1;
        next_free = -1;
        /* Cba to set next_free to the next free block because I'm /hc/.
         *Besides that, it'd defeat the point of having it (which was so
         * we wouldn't have to search for free blocks immediately after
         * a free).
         */
        return p;
    } else {
        /* Look for a big enough free block.
         */
        void* p;
        size_t i;
        for (i = 0; i < num_shitblocks; ++i) {
            if ((shitblocklist[i].used == 0) && (shitblocklist[i].size >= size)) {
                shitblocklist[i].used = 1;
                return shitblocklist[i].start;
            }
        }
        /* If we haven't returned yet we need to take a new shit.
         */
        p = sbrk(sizeof(*shitblocklist) * (num_shitblocks + 1));
        if (!(p))
            return NULL;
        /* Copy the old list and add the new shitblock.
         */
        memcpy(p, shitblocklist, sizeof(*shitblocklist) * (num_shitblocks + 1));
        shitblocklist[num_shitblocks].start = sbrk(size);
        shitblocklist[num_shitblocks].size  = size;
        shitblocklist[num_shitblocks].used  = 1;
    }
    return NULL;
#endif
    /* OH FUCK LOOK AT ALL THAT HEAP ALLOCATION I DID MAN THAT WAS NICE. */
}

/**
 * \brief    Allocates a block of shit and sets every
 * \param count    The number of elements in the shit-block.
 * \param size    The size in bytes of each shit-element.
 * \return    On success, a pointer to the shit-block is returned. On error,
 *        NULL is returned.
 */
void* ztake_shit(size_t count, size_t size)
{
#if defined(WINDOWS)
    return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
#elif defined(POSIX)
    void* shit = take_shit(count * size);
    if (shit)
        memset(shit, 0, count * size);
    return shit;
#endif
}

/**
 * \brief    Resizes a block of shit.
 * \param shit    A pointer to the shit-block to be resized.
 * \param new_size The new size of the shit-block.
 * \return    On success, the resized shit-block is returned. On error, NULL
 *        is returned.
 */
void* resize_shit(void* shit, size_t new_size)
{
#if defined(WINDOWS)
    return HeapReAlloc(GetProcessHeap(), shit, new_size);
#elif defined(POSIX)
    void* new_shit = take_shit(new_size);
    if (new_shit) {
        memcpy(new_shit, shit, size);
        flush_shit(shit);
    }
    return new_shit;
#endif
}

/**
 * \brief    Flushes a block of shit.
 * \param shit    The shit-block to flush. If this is a null pointer, no action is
 *        performed.
 */
void flush_shit(void* shit)
{
    if (!(shit))
        return;
#ifdef WINDOWS
    HeapFree(GetProcessHeap(), 0, shit);
#elif defined(POSIX)
    size_t i;
    if (sbrk(0) == shit) {
        /* Give memory at the end of the program-break back to the OS.
         */
        for (i = 0; i < num_shitblocks; ++i) {
            if (shitblocklist[i].start == shit) {
                sbrk(0 - shitblocklist[i].size);
                return;
            }
        }
    } else {
        /* Mark the block free so take_shit() can use it later.
         */
        for (i = 0; i < num_shitblocks; ++i) {
            if (shitblocklist[i].start == shit) {
                shitblocklist[i].used = 0;
                return;
            }
        }
    }
#endif
}


I spent, maybe, 30 minutes on this?

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List