Prog 7
Prog 7
03 - Structures
A word on malloc(3)
#include <err.h>
#include <stdlib.h>
int main()
{
int *p1 = malloc(sizeof (int));
if (p1 == NULL) // handle error !
err(1, "malloc failed");
int *p2 = calloc(42, sizeof (int));
if (p2 == NULL) {
free(p1);
err(1, "calloc failed");
}
int *p3 = realloc(p2, 64 * sizeof (int));
if (!p3) {
free(p1);
free(p2);
err(1, "realloc failed");
}
p2 = p3;
free(p1);
free(p2);
return 0;
}
Data Structures
Data Structures
struct demo
{
uint8_t f1;
uint64_t f8;
uint32_t f4;
};
int main()
{
printf("sizeof (struct demo) = %zu\n", sizeof (struct demo));
printf("Layout:\n");
printf(" f1: %zu\n", offsetof(struct demo, f1));
printf(" f8: %zu\n", offsetof(struct demo, f8));
printf(" f4: %zu\n", offsetof(struct demo, f4));
return 0;
}
Struct Layout
In 64bit:
sizeof (struct demo) = 24
Layout:
f1: 0
f8: 8
f4: 16
In 32bit:
sizeof (struct demo) = 16
Layout:
f1: 0
f8: 4
f4: 12
Arrays In Struct
struct s_user {
unsigned uid, gid;
char login[16];
};
int main() {
struct s_user u;
printf("u.login:\t%p\n",u.login);
printf("&(u.login):\t%p\n",&(u.login));
return 0;
}
Arrays In Struct
u.login: 0x7fffed0045b0
&(u.login): 0x7fffed0045b0
More examples
struct user
{
unsigned uid, gid;
char login[16];
};
/* arrays of structs */
struct user* find_user(struct user users[], size_t len, unsigned uid)
{
struct user *cur = users;
for (; cur != users + len && cur->uid != uid; cur++)
continue;
return cur;
}
More examples
/* vectors */
struct vector
{
size_t capacity, size;
int *store;
};
/* matrix */
struct matrix
{
size_t w, h;
double *mat;
};
Recursive Structure
struct list {
struct list *next;
int value;
};
Lists
Linked Lists
for (; l; l = l->next) {
// work on element
}
List Length
sentinel
Example
void list_remove(struct list **list, struct list *elm)
{
struct list *cur = *list;
struct list *prev = NULL;
for (; cur != elm; cur = cur->next)
prev = cur;
if (prev == NULL)
*list = cur->next;
else
prev->next = cur->next;
}
struct queue {
struct queue *next;
void *value;
};
Newest
Oldest
Queue Push
struct queue* queue_push(struct queue *q, void *x) {
struct queue *tmp;
tmp = malloc(sizeof (struct queue));
tmp->value = x;
if (q) {
tmp->next = q->next;
q->next = tmp;
} else {
tmp->next = tmp;
}
return tmp;
}
Queue Pop
struct tree {
// Children
struct tree *left, *right;
// Content
int key;
};
Binary Tree
// Compute size
size_t tree_size(struct tree *t) {
if (t == NULL)
return 0;
return 1 + tree_size(t->left) + tree_size(t->right);
}
// Compute height
static inline int max(int a, int b) { return a > b ? a : b; }
// Prefix print
void prefix_print(struct tree *t) {
if (t) {
printf("%d; ", t->key);
prefix_print(t->left);
prefix_print(t->right);
}
}
Binary Tree
// Breadth first print
void breadth_print(struct tree *t) {
if (t) {
struct queue *q = queue_empty();
q = queue_push(q, t);
q = queue_push(q, NULL);
do {
t = queue_pop(&q);
if (t == NULL) {
printf("\n");
if (!queue_is_empty(q))
q = queue_push(q, NULL);
} else {
printf("%d ", t->key);
if (t->left)
q = queue_push(q, t->left);
if (t->right)
q = queue_push(q, t->right);
}
} while (!queue_is_empty(q));
}
}