control: performance, resource
low-level & error-prone (cache, concurrency)
typedef int T;
struct vector {
size_t size;
T *data;
};
struct vector *vector_alloc(size_t n, T initial_val);
void vector_free(struct vector *s);
example use:
int main(void) {
size_t i, n = 10;
struct vector *s = vector_alloc(n, 42);
/* ... */
vector_free(s);
}
struct vector {
size_t size;
T *data;
};
struct vector *vector_alloc(size_t n, T initial_val) {
struct vector *s = malloc(sizeof(struct vector));
s->size = n;
s->data = malloc(n * sizeof(T));
for (size_t i = 0; i < n; ++i)
s->data[i] = initial_val;
return s;
}
void vector_free(struct vector *s) {
free(s);
free(s->data);
}
malloc
may failsee vector_0.c
struct vector {
size_t size;
T data[];
};
struct vector *vector_alloc(size_t n, T initial_val) {
struct vector *s = malloc(sizeof(struct vector) + n * sizeof(T));
s->size = n;
for (size_t i = 0; i < n; ++i)
s->data[i] = initial_val;
return s;
}
void vector_free(struct vector *s) {
free(s);
}
see vector_1.c
struct vector_0 {
size_t size;
T *data;
};
struct vector_1 {
size_t size;
T data[];
};
sizeof(struct vector_0)
vs sizeof(struct vector_1)
?
try printf
the results
struct snap_context {
...
size_t num_snaps;
uint64_t snaps[];
};
struct snap_context *ctx;
size_t num = ...;
if (num > SIZE_MAX / sizeof(uint64_t) - sizeof(*ctx))
goto fail;
ctx = malloc(sizeof(*ctx) + num * sizeof(uint64_t));
see bug & fix
typedef int T;
struct slist {
T elem;
struct slist *next;
};
struct slist *slist_push(struct slist *lst, T e);
struct slist *slist_push(struct slist *lst, T e) {
struct slist *n = malloc(sizeof(struct slist));
/* TODO: check if n is NULL */
n->elem = e;
n->next = lst;
return n;
}
int main(void) {
struct slist *lst = NULL;
lst = slist_push(lst, 12);
lst = slist_push(lst, 34);
lst = slist_push(lst, 56);
}
Example: Linux kernel
struct person {
char name[32];
long ident;
struct list_head list;
};
int main(void) {
struct person alice = {"alice", 42}, bob = {"bob", 24}, *p;
LIST_HEAD(lst);
list_add(&alice.list, &lst);
list_add(&bob.list, &lst);
list_for_each_entry(p, &lst, list) {
printf("%s:\t%ld\n", p->name, p->ident);
}
}
see list.h and test_list.c
.h
files: headers, to be #include
’d
.c
files: definitions.o
files - executablereview CSE 351 / tomorrow’s sections
complete the singly linked list:
slist_pop
implement and test a binary search tree
insert()
and lookup()
functionsdelete()
functionbst.c
and bst.h
test_bst.c
: main()
to test out your BST