/*
Compile:
make readme-ex01d-using-struct
*/
#define _BSD_SOURCE /* snprintf(), strndup() */
#include <string.h> /* strlen() */
#include <stdio.h> /* printf() */
#include <stdlib.h> /* calloc() */
/* HTML header levels */
typedef enum header_level
{
h1 = 1,
h2,
h3,
h4,
h5,
h6
} header_level;
typedef struct html_header
{
header_level level;
char *title;
} html_header;
typedef struct node_struct_t
{
html_header data; /* NOT VERY GENERIC */
struct node_struct_t * next;
} node_struct_t;
/* Delete data for all but the 3 first nodes, as they contain static data, and should not be free():ed */
void data_cleanup(node_struct_t **node)
{
node_struct_t *current = *node;
while (current)
{
free(current->data.title);
current = current->next;
}
}
/* Delete all nodes */
void node_cleanup(node_struct_t **head)
{
node_struct_t *current = *head, *next = NULL;
while (current)
{
next = current->next;
free(current);
current = next;
}
/* Set variable to NULL *before* free(). */
/* Valgrind doesn't like it the other way around! */
*head = NULL;
free(*head);
}
int
main(int argc, char *argv[])
{
node_struct_t *node1 = calloc(1, sizeof(*node1));
node_struct_t *node2 = calloc(1, sizeof(*node2));
node_struct_t *node3 = calloc(1, sizeof(*node3));
node_struct_t *node = calloc(1, sizeof(*node));
int i = 0;
printf("\nREADME EX01d\n");
printf("----------------------------------------\n");
node1->data.level = 1;
node1->data.title = "Header 1";
node2->data.level = 2;
node2->data.title = "Header 2";
node3->data.level = 3;
node3->data.title = "Header 3";
node1->next = node2;
node2->next = node3;
node3->next = NULL;
printf("node1->data={%d, '%s'}\n", node1->data.level, node1->data.title);
printf("node1->next->data={%d, '%s'}\n", node1->next->data.level, node1->next->data.title);
printf("node1->next->next->data={%d, '%s'}\n", node1->next->next->data.level, node1->next->next->data.title);
/* Create another 100 nodes, link first node to node3 */
for (i = 0; i < 100; ++i)
{
#define BUFSIZE 256
char buf[BUFSIZE];
if (i == 0) node3->next = node;
snprintf(buf, BUFSIZE, "This is node number %d", i+3);
node->data.title = calloc(1, strlen(buf)+1);
memcpy(node->data.title, buf, strlen(buf)+1);
node->next = calloc(1, sizeof(*node));
node = node->next;
}
/* Print node 42 of 103 - should print "This is node number 42" */
node = node1;
for (i = 0; i < 42; ++i)
{
node = node->next;
}
printf("%s\n", node->data.title);
/* Cleanup dynamic data, skipping 3 first nodes */
data_cleanup(&node3->next);
/* Delete all nodes */
node_cleanup(&node1);
printf("\nTIP: MEMLEAK CHECK:\n");
printf("valgrind -v --track-origins=yes --leak-check=full --show-leak-kinds=all %s\n", argv[0]);
(void)argc;
printf("----------------------------------------\n\n");
return 0;
}