You are on page 1of 5

Programming for MSc Part I Part 5: Dynamic Data Structures

(a) Allocating and Releasing Memory

Why Dynamic Structures

• Sometimes we don’t know how much memory we need


• Example: How many lines has a text document?
−→ Here we are helpless with what we know so far
• Solution: Create objects of necessary size at runtime
• But: Don’t forget to dispose of memory not needed anymore

The ‘malloc’ and ‘free’ Functions

• The malloc() and free() functions are declared in the


header stdlib.h:
void *malloc(size t size);
void free(void *ptr);
• malloc() allocates an object of size Bytes and returns a
pointer to the result
• free() releases memory previously allocated by malloc()
• The void* pointer represents an address without type
• It must be assigned to a typed pointer
• The result is something like a dynamic array

Herbert Martin Dietze <herbert@the-little-red-haired-girl.org> 68


Programming for MSc Part I Part 5: Dynamic Data Structures — Allocating and Releasing

A Longer ‘malloc’ Example

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

int main (void)


{
int i, lines;
char **text;
printf ("How many lines?\n");
scanf ("%d", &lines), getchar ();
text = malloc (lines * sizeof (*text));
for (i = 0; i < lines; i++)
{
text[i] = malloc (256 * sizeof (*text[i]));
fgets (text[i], 256, stdin);
}
for (i = 0; i < lines; i++)
{
printf ("%s", text[i]);
}
for (i = 0; i < lines; i++)
{
free (text[i]);
}
free (text);
return 0;
}

Herbert Martin Dietze <herbert@the-little-red-haired-girl.org> 69


Programming for MSc Part I Part 5: Dynamic Data Structures — Allocating and Releasing

Resizing Allocated Memory

• Sometimes allocated memory blocks grow or shrink


• This can be done using the realloc() function:
void *realloc (void *ptr, size t size);
• It resizes the memory at ptr to size Bytes and returns a new
pointer to the result
• However this operation is expensive in performance
• A good strategy: Use fixed block sizes larger than necessary

Example:

int block = 10;


int size = 10;
int i = 0;
char **txt = malloc (size * sizeof (*txt));
txt[i] = malloc (256 * sizeof (*txt[i]));

while (fgets (txt[i], 256, stdin) != NULL)


{
++i;
if (i >= size)
{
size += block;
txt = realloc (txt, size * sizeof (*txt));
}
txt[i] = malloc (256 * sizeof (*txt[i]));
}

Herbert Martin Dietze <herbert@the-little-red-haired-girl.org> 70


Programming for MSc Part I Part 5: Dynamic Data Structures

(b) List Structures

Lists

• Many problems in computing deal with list structures:


– Elements of the same type
– Number of elements constantly changing
– Access rules, like First-In-First-Out or Last-In-First-Out
– Quick find: sorting while inserting
• Due to the problem’s nature we need dynamic structures here
• Implementations using realloc() may be inefficient (e.g.
when sorted lists are required)

A Data Structure for Linked Lists

• Basic idea:
– Every list element consists of the data plus a pointer to
the next element
– When the pointer is NULL we are at the last element
– We keep only the reference to the first element
• Physical layout:
typedef struct node {
int data;
struct node *next;
} *list;

Herbert Martin Dietze <herbert@the-little-red-haired-girl.org> 71


Programming for MSc Part I Part 5: Dynamic Data Structures — List Structures

List Operations

List creation: list list mk empty (void)


List attribute: int list is empty (list l)
List attribute: int list is in (list l, int i)
New element: void list insert (list *l, int e)
Element access: int list first (list *l)
List deletion: void list delete (list *l)

Example: New Element

void list_insert (list *l, int e)


{
struct node *tmp = malloc (sizeof (*tmp));
tmp->data = e;
tmp->next = *l;
*l = tmp;
}

Example: Deletion

void list_delete (list *l)


{
while (*l != NULL)
{
(void)list_first (l);
}
}

Herbert Martin Dietze <herbert@the-little-red-haired-girl.org> 72

You might also like