Below is our list example code.
list.h
#ifndef __LIST_H__
#define __LIST_H__
typedef struct {
unsigned length;
int *array;
} List;
// Construct, destruct
List *makeList();
void destroyList(List *);
// Add to end of list
void append(List *list, int val);
#endif
list.c
#include <stdlib.h>
#include "list.h"
List *makeList() {
// Space for a List struct
List *ans = (List *) malloc(sizeof(List));
// Initially an empty list
ans->length = 0;
ans->array = (int *) malloc(ans->length * sizeof(int));
return ans;
}
void destroyList(List *list) {
// Avoid use after free! Free array first.
free(list->array);
free(list);
}
// Example code (not shown in lecture):
void append(List *list, int val) {
// Increase the size of the list by 1
list->length += 1;
// Reallocate the memory for our array to include more space.
// realloc() will copy over the original bytes, but no guarantees
// on the other bytes after that.
list->array = (int *) realloc(list->array, list->length * sizeof(int));
// Store the new value at the end of the array.
list->array[list->length - 1] = val;
}
useList.c
This is some example code that uses the list above. Note that we #include "list.h" so that the typechecker knows what our list looks like and what the functions are. We will then compile this by compiling both C files together: clang list.c useList.c.
#include <stdio.h>
#include "list.h"
int main() {
List *myList = makeList();
printf("%p\n", myList);
// Append some values
append(myList, 42);
append(myList, 175);
// Print out the list
for (int i = 0; i < myList->length; i+=1) {
printf("%d\n", myList->array[i]);
}
puts(""); // To get a new line
return 0;
}