COMS 3157 Advanced Programming

Recitation 11: Malgrind

You can find the code and solutions for this recitation on CLAC, here:

$ git clone ~j-hui/cs3157-pub/examples/malgrind

Consider malgrind.c, which defines MALLOC() and FREE():

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

static uint64_t MAGIC = ~((uint64_t) 0);

const size_t WAD = sizeof(MAGIC);

void *MALLOC(size_t n) {
    char *p = malloc(2 * WAD + n);
    if (p == NULL)
        return NULL;

    uint32_t *head = (uint32_t *)p;
    head[0] = head[1] = n;
    memcpy(p + WAD + n, &MAGIC, WAD);
    return p + WAD;
}

void FREE(void *p) {
    if (p == NULL) {
        fprintf(stderr, "%s\n", "NULL");
        return;
    }

    uint32_t *head = (uint32_t *)p - 2;
    if (head[0] != head[1] || memcmp((char *)p + head[0], &MAGIC, WAD) != 0)
        fprintf(stderr, "%s\n", "OOPS");
    else
        fprintf(stderr, "%s\n", "OKAY");

    free((char *)p - WAD);
}

MALLOC() and FREE() provide the same interface as the underlying malloc() and free() functions, in that they allocate and release heap memory. Which following describe the potential benefits of using MALLOC() and FREE() instead of the malloc() and free() functions they wrap?

Select zero or more of the above. You do not have to answer this right now; work on some of the problems below before returning to these questions.

11.1 mgtest1

Here is a test program, mgtest1.c, which uses the MALLOC() and FREE() functions:

#include <stdio.h>

void *MALLOC(size_t n);
void FREE(void *p);

int main(void) {
    int *a = MALLOC(4 * sizeof(int));

    for (int i = 0; i < 5; i++)
        a[i] = i;

    for (int i = 0; i < 5; i++)
        fprintf(stderr, "%d, ", a[i]);

    FREE(a);

    return 0;
}

We compiled and linked the mgtest1 program, and ran it with and without Valgrind:

$ gcc -g -Wall mgtest1.c malgrind.c -o mgtest1

$ valgrind --leak-check=yes ./mgtest1           # with Valgrind
(( output not shown ))

$ ./mgtest1                                     # without Valgrind
(( output not shown ))

What is the outcome of running mgtest1 with Valgrind? Choose from one of the following:

What is the output of the program, when run without Valgrind?

11.2 mgtest2

We replace mgtest1.c with a modified version of the test, mgtest2.c:

#include <stdio.h>
#include <assert.h>

void *MALLOC(size_t n);
void FREE(void *p);

int main(void) {
    assert(sizeof(long) == sizeof(void *));

    long *a = MALLOC(4 * sizeof(long));

    for (long i = 0; i < 4; i++)
        a[i] = i;

    for (long *p = a; *p >= 0; p++)
        fprintf(stderr, "%ld, ", p[1]);

    FREE((void *) *a);

    return 0;
}

Like before, we compiled and linked the mgtest2 program, and ran it with and without Valgrind:

$ gcc -g -Wall mgtest2.c malgrind.c -o mgtest2

$ valgrind --leak-check=yes ./mgtest2           # with Valgrind
(( output not shown ))

$ ./mgtest2                                     # without Valgrind
(( output not shown ))

What is the outcome of running mgtest2 with Valgrind? (ERROR/LEAK/GOOD)

What is the output of the mgtest2 program, when run without Valgrind? (Comma-separated decimal integers + word, same rules as before.)

11.3 mgtest3

Here’s another variation of the test program, mgtest3.c:

#include <stdio.h>
#include <assert.h>

void *MALLOC(size_t n);
void FREE(void *p);

int main(void) {
    assert(sizeof(int) == 4);

    int *a = MALLOC(4 * sizeof(int));

    for (int i = 0; i < 4; i++)
        a[i] = i;

    for (int *p = a - 2; p < a + 6; p++)
        fprintf(stderr, "%d, ", *p);

    FREE(a);

    return 0;
}

Like before, we compiled and linked the mgtest3 program, and ran it with and without Valgrind:

$ gcc -g -Wall mgtest3.c malgrind.c -o mgtest3

$ valgrind --leak-check=yes ./mgtest3           # with Valgrind
(( output not shown ))

$ ./mgtest3                                     # without Valgrind
(( output not shown ))

What is the outcome of running mgtest3 with Valgrind? (ERROR/LEAK/GOOD)

What is the output of the mgtest3 program, when run without Valgrind? (Comma-separated decimal integers + word, same rules as before.)