#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define STRINGIZE(x) #x
#define LINEFILE(x) "Line " STRINGIZE(x) " of File " __FILE__
#define LINE_FILE LINEFILE(__LINE__)

/* Comment out the next line to disable debugging diagnostics. */
#define DEBUG_D
#ifdef DEBUG_D
/* Debugging functions and variables. */
static unsigned long malloc_b = 0;
static unsigned long malloc_c = 0;
static unsigned long free_c = 0;

static inline void* dmalloc(size_t size);
static inline void dfree(void* object);
static inline void dprintc(void);

static inline void* dmalloc(size_t size)
{
    malloc_b += size;
    ++malloc_c;
    return malloc(size);
}

static inline void dfree(void* object)
{
    free(object);
    ++free_c;
}

static inline void dprintc(void)
{
    fprintf(stderr, "\nAllocated %lu bytes; malloc() called: %lu.\nfree() called: %lu.\n",
            malloc_b, malloc_c, free_c);
}

#define malloc dmalloc
#define free dfree

#endif /* ifdef DEBUG_D */

static inline void swap(void* A, void* B, size_t size);

int main(void)
{
    unsigned long long mb;
    mb = 0;
    while (malloc(sizeof(char) << 20)) ++mb;
    ++mb;
    printf("Allocated %llu megabytes Total.\n", mb);
    dprintc();
    return 0;
}

static inline void swap(void* A, void* B, size_t size)
{
    char* temp;
    temp = malloc(size);
    if (temp)
    {
        memcpy(temp, A, size);
        memcpy(A, B, size);
        memcpy(B, temp, size);
        free(temp);
    }
}