C Lecture 7
[Previous Lecture]
[Lecture Index]
[Next Lecture]
Dynamic Memory Allocation
Used to:
- create data structures like lists and trees
(can't use a variable for each item)
- avoid limits created by using fixed sized arrays
Memory allocation routines
- void *malloc(int size)
- allocate size bytes
- memory contents undefined
- void *calloc(int size, int nelem)
- allocate sizes * nelem bytes
- memory contents zeroed
- void *realloc(void *old, int newsize)
- changes size of previously allocated memory
- may return different piece of memory
- expanded memory contents undefined
- void free(void *old)
- releases allocated memory
(so it can be re-used)
Notes:
- allocated memory can be used for any data type
- must cast return value to appropriate type
- use sizeof to determine how much space is needed
bin-tree.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
struct bin_tree {
int key;
char *str;
struct bin_tree *left;
struct bin_tree *right;
};
struct bin_tree *tree_addto(
struct bin_tree *root,
int key, char *str);
struct bin_tree *tree_search(
struct bin_tree *root,
int key);
void tree_delete(
struct bin_tree *root);
int
main()
{
FILE *fp;
int key;
char buf[1024];
struct bin_tree *root = 0;
struct bin_tree *node;
int i;
fp = fopen("data.file", "r");
if (!fp) {
fprintf(stderr, "can't open %s - %s\n",
"data.file", strerror(errno));
return 1;
}
while (fscanf(fp, "%d %s", &key, buf)
== 2)
{
root = tree_addto(root, key, buf);
if (!root) {
fprintf(stderr,
"can't save entry - %s\n",
strerror(errno));
return 1;
}
}
fclose(fp);
i = 8;
node = tree_search(root, i);
if (node)
printf("string for key %d is %s\n",
i, node->str);
else
printf("no node with key %d\n", i);
tree_delete(root);
return 0;
}
struct bin_tree *
tree_addto(struct bin_tree *root,
int key, char *str)
{
struct bin_tree *new;
struct bin_tree *node, **prevp;
new = (struct bin_tree *)
malloc(sizeof(struct bin_tree));
if (!new || !(new->str = strdup(str))) {
if (new)
free(new);
return 0;
}
new->key = key;
new->left = 0;
new->right = 0;
prevp = &root;
while (*prevp) {
node = *prevp;
prevp = key < node->key ?
&node->left : &node->right;
}
*prevp = new;
return root;
}
struct bin_tree *
tree_search(struct bin_tree *root, int key)
{
struct bin_tree *node = root;
while (node) {
if (node->key == key)
break;
node = key < node->key ?
node->left : node->right;
}
return node;
}
void
tree_delete(struct bin_tree *root)
{
if (!root)
return;
tree_delete(root->left);
tree_delete(root->right);
free(root->str);
free(root);
}
[Previous Lecture]
[Lecture Index]
[Next Lecture]