V Lecture 12 — more memory management, hw4, header files
* reminder: check remaining late days, no credit for late work
* midterm review 2 - 3 p.m. on Saturday, room TBD
V heap allocation review
V picture of memory
V void *malloc(size_t size)
V void* calloc (size_t num, size_t size);
* takes the number of things and the size of each thing as separate parameters
* initializes all the allocated memory with zeros
* use sizeof to allocate memory for non-char types
* void free(void *ptr)
V if we have
typedef struct {
char *str;
int len;
} String;
V exercise: what is the size of String?
* 8 bytes for char* + 4 bytes for int = 12 bytes
* we allocate one like this
String *s = malloc(sizeof(*s));
* of an array of them like this
String *s = malloc(10 * sizeof(*s));
or this
String *s = calloc(10, sizeof(*s));
* be aware: with malloc, you will need to initialize members to null if you want to be able to check if they have been initialized
* in any case, free the memory like this
free(s);
* be aware: this does not allocate memory for the characters of str, just memory for the pointer itself
V exercise: where is the memory leak?
V int main (int argc, char **argv) {
int **matrix;
matrix = malloc (3 * sizeof (*matrix));
for (int i = 0; i < 3; i++) {
matrix[i] = malloc(5 * sizeof(*matrix[i]));
}
free(matrix);
}
* free is shallow, so while the memory allocated to matrix is freed, the memory allocated to the elements of matrix is not
V header files
V why would we want the ability to separate code into multiple files
* more readable, maintainable
* abstraction
* compilation
V header files (.h files) are how you share code between .c files
* struct definitions, function prototypes (declarations), #defines, and #includes
* no function definitions (leave that to the appropriate .c file)
* putting the #include target in " " searches the current directory (< > searches the standard library)
V can think of .h vs .c as public vs private
* .h in some ways provide an interface
V to avoid problems with double inclusion or mutually recursive inclusion, use #ifndef
* Any header file, such as some_header.h, should begin with
#ifndef SOME_HEADER_H
#define SOME_HEADER_H
// actual header code
#endif
V #ifdef and #ifndef are an example of conditional compilation
* the preprocessor uses or discards the enclosed code accordingly
* tests whether something has been #define-ed (or not)
V exercise: write a function debug_printf(char *format_str) that uses the preprocessor define DEBUG to determine whether it prints anything
* void debug_printf(char *output) {
#ifdef DEBUG
printf(output);
#endif
return;
}
V you can even set something to be defined as part of the gcc command with -D
* gcc -D Debug …
V homework 4
V Implement the T9 (text on 9 keys) system, without the predictive part
* so just the ability to encode words as a series of digits 2-9
V interactive command-line program
* 729 -> ‘paw’
* 729# -> ‘pax’
* 729## -> ‘pay’
V core idea: represent this dictionary using a tree-based data structure called a trie
* the position of a node in the tree defines the key at that node
V organization
V trie data structure
* struct representing a node (recursive data structure)
V functions:
* create/init
* insert
* lookup
* destroy
* trie.h — declarations
* trie.c — implementation
V main
* #include “trie.h”
* probably shouldn’t define any structs, additional functions, etc.