Announcements
- Today's Schedule
- Short Quiz #4
- Exam #1 topics
- Complete discussion on dynamic memory allocation
- User-defined types
- The comma operator
- Monday we will start talking about large program development
- Unless you have questions for the exam...
Exam #1 Topics
- First hourly exam is next Friday, in class
- Exam is closed book, closed notes, except for a 1 page 'cheat sheet' which you will also hand in
- Covers all readings listed on the schedule including Monday, plus
everything we've done in class or homeworks/projects
- Expect mixture of short answers, T/F and multiple choice, and short
programming exercises
- Major topics include:
- Using UNIX
- C Language and Programming
- Pointers and Storage Management
Finish Monday's discussion
- We had been discussing dynamic memory allocation
- Mentioned a simple routine to expand the size of a dynamically
allocated array of integers (posted online
here)
- Realized need for pointers to pointers
- We have a few more issues to cover w.r.t. pointers...
Functions that return pointers
- When using routines that return pointers, you must determine who is
responsible for the memory
- Possibilities include:
- Pointer is to a global value -- memory never needs to be free()d, but
might get overwritten by later function calls (e.g., some networking
code)
- Pointer is to a dynamically-allocated local structure that must be
destroyed/freed with another library call
- Pointer is to a dynamically-allocated block of memory that your code
must later free (e.g., strdup())
- Pointer is to a portion of some other block of memory that could later
move or be freed independently of this pointer
(e.g., strstr())
- In general, you need to know if
- You are now responsible to free() this memory
- This memory might get overwritten in the future
Generally, either you need to free() or this is memory that you have no
control over...
Stack/Heap
- Finally, it is sometimes useful to think about exactly where
all this memory really is in your program.
- Let's consider the typical memory model for UNIX processes.
- The stack contains each calling frame of each function invocation, which are popped when the function returns.
- The heap contains dynamically allocated memory.
- The stack and heap grow toward each other.
Why can't malloc'd data be on the stack?
User-Defined Structures
- We have previously mentioned structs, as in
struct complex {
double real;
double imag;
};
which defined a new type
struct complex.
We could also have declared some new variables of that type, in two
ways:
struct complex {
double real;
double imag;
} var1, var2;
struct complex var3, var4;
Access to Structs
- We also saw that we could access contents using the period operator:
var1.real = var2.real + var3.real;
Pointers to structs work as expected:
struct complex *p1, *p2;
p1 = &var1;
printf("%lf\n", (*p1).real);
Parentheses are needed. Could instead use -> operator:
printf("%lf\n", p1->real);
which is an equivalent (and common) shortcut.
User-defined types
- A struct is a user-defined type
- Sometimes we have a need/desire to define new type names
- for convenience
- to make the code more self-documenting
- to make it possible to change the actual base type used for a lot of
variables without rewriting the declarations of all those variables
Typedef
- The typedef operator permits us to use an alternate name
for a defined type. Thus,
typedef char *StringPtr;
typedef struct complex Complex;
StringPtr string;
Complex c1, c2;
would be equivalent to
char *string;
struct complex c1, c2;