CS 330 Lecture 11 – Call by *, Addresses, Malloc
Agenda
- what ?s
- call by value
- call by reference
- dereferencing: turning an address into a value
- what pointers support
- cheap sharing
- multiple “return” values
- functions returning data: make_path
- the heap
- aplay -c 2 -f S16_LE -r 22050
- pointer arithmetic
- malloc and free
TODO
- Optionally, for the curious: http://cm.bell-labs.com/cm/cs/who/dmr/chist.html.
- Read sections 3.7 and 3.8. Quarter sheet.
Code
bookmarks.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct bookmark_t {
char title[256];
char url[256];
};
void print(struct bookmark_t *mark);
int main(int argc, char **argv) {
struct bookmark_t bookmark = {"Reddit", "http://www.reddit.com"};
print(&bookmark);
printf("bookmark.title: %s\n", bookmark.title);
/* bookmark.title = */
return 0;
}
void print(struct bookmark_t *mark) {
strcpy(mark->title, "ALL UR BASE R BELONG TO US");
printf("<a href=\"%s\">%s</a>\n", mark->url, mark->title);
}
math_stuff.c
#include <stdio.h>
#include <stdlib.h>
void divrem(int numerator,
int denominator,
int *quotient,
int *remainder);
int main(int argc, char **argv) {
int quotient;
int remainder;
divrem(12, 0, "ient, &remainder);
printf("quotient: %d\n", quotient);
printf("remainder: %d\n", remainder);
return 0;
}
void divrem(int numerator,
int denominator,
int *quotient,
int *remainder) {
*quotient = numerator / denominator;
*remainder = numerator % denominator;
}
weakly_typed.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
float n = 17.0f;
int *address = (int *) &n;
*address = 3984753;
printf("n: %e\n", n);
return 0;
}
path.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *make_path(char dir[], char file[]) {
char *path = (char *) malloc(sizeof(char) * 256);
strcpy(path, dir);
strcat(path, "/");
strcat(path, file);
return path;
}
int main(int argc, char **argv) {
char dir[] = "/home/johnch";
char file[] = "days_of_our_lives.mp4";
char *path = make_path(dir, file);
printf("path: %s\n", path);
free(path);
path = NULL;
/* printf("path: %s\n", path); */
return 0;
}
Why?
- Why a stack? Accommodating new storage needs is O(1): push or adjust the stack pointer. A stack reflects the nature of function calling. A calls B, B calls C. C’s data is not visible to A and B, so when it finishes and these values go out of scope, we remove its data by popping the stack, another O(1) operation.
- Why a heap? With only a stack, a function has limited choices on how to give data back to the caller. Often this is done through a return value. If this data is very large, the return-by-value mechanism will mean a lot memory is getting copied. Large data could also be “returned” to the caller without an expensive copy operation if the caller sends along an address to write to as one of the function’s parameters. This puts the burden of allocating sufficient storage on the caller, which violates the separation of concerns. Also, releasing storage that’s not at the top of stack becomes problematic. Some differently organized and managed memory is necessary. We need a system that is not tied to the call chain or the last-in-first-out rules of the stack.
Haiku
Friend’s son will mow lawns.
Mailman wouldn’t send him mine.
Gave address instead.
Mailman wouldn’t send him mine.
Gave address instead.