Professional Documents
Culture Documents
"##$
Controlling formatting
We can supply a field width, precision, and other flags to format our output exactly as we want
%04x : format as unsigned hex number, with 4 spaces and zero padding %-10s : format as string, allot 10 spaces, left justify (default is right justify) %6.4f : format as floating point, allot 6 spaces, 4 digits after the decimal point
Chapter 6, Reek
POINTERS
12
($
!"!!"##$
Pointers
Pointers are variables whose value is an address Every variable is stored at an address in memory We use pointers to perform manipulation of memory, by accessing items at the address stored in the pointer
13
Declaration of pointers
A pointer to an int value would be declared like this: int *ip; Creates a variable called ip, whose type is "pointer to int" We can assign the address of an int variable to be the value of this new pointer
14
)$
!"!!"##$
Pointer operators
Obtaining the address of an object (&)
Placed before a variable (or an object in memory)
Example:
Memory
Address
i 6 1084 int i = 6; p 1084 1088 int *p; p = &i; printf("%d %d\n", *p, *(&i));
15
16
*$
!"!!"##$
Garbage pointers
When a pointer is declared, it points to whatever address was in the memory location allocated for the pointer (no initialization) Trying to dereference this random address will generally result in one of three Bad Things:
accessing a memory location you don't have permission to access (a "segmentation fault") violating the computer's alignment policies (a "bus error") silent failure: everything appears to work right... for now
17
NULL pointer
This is a pointer that points to the address 0, where nothing is allowed to be accessed Defined in stddef.h, which is included by many other header files Analogue to Java's null
What happens when you try to call a method of an object which is null? Very similar thing happens in C when trying to dereference a NULL pointer; it's usually a segfault
Just like in Java, you have to check pointers to see if they're NULL before dereferencing them:
void f(int *p) { if (p != NULL) *p = 55; }
18
+$
!"!!"##$
Pointers to Pointers
You can also obtain the address of a pointer variable: Memory Address
int i = 4; int j = 6; int *p = &i; int *q = &j; int **r = &p; printf("%d\n", **r); *r = &j; printf("%d\n", *p);
i j p q r 4 6 1088 1088 1092 1084 1088 1092 1096 1100
Pointers as parameters
You can also pass addresses into a function:
void swap(int *a, int *b) { int tmp = *a; *a = *b; *b = tmp; } ... int x = 2; int y = 3; swap(&x, &y); printf("%d %d\n", x, y);
#,$
!"!!"##$
##$
!"!!"##$
Remember that the -> is doing dereferencing; you must perform the NULL check before the pointer is dereferenced!
23
Generic pointers
Pointers to void (void *) can point to any type:
void *vp; int a, *ip; double b, *dp; vp = &a; ip = vp; vp = &b; dp = vp; vp = ip;
#!$
!"!!"##$
NULL is really defined as (void *) 0 These allow use of generic code, but misuse can lead to the kinds of errors we've seen before:
void *vp; int *ip; double a = 3.14159; vp = &a; ip = vp; printf("%d\n", *ip);
/* -266631570 */
25
#%$
!"!!"##$
28
#&$
!"!!"##$
Order of type specifier and const modifier does matter when dealing with pointers:
int i = 4, j = 5; const int *p = &i; int * const q = &j; p = &j; /* OK */ *p += 5; /* ERROR q = &i; /* ERROR *q += 23; /* OK */ /* pointer to constant int */ /* constant pointer to int */ */ */
The program cdecl (or http://cdecl.org) can be useful for decoding some more complex declarations
29
Incrementing pointers
Pointers can be incremented/decremented just like integer type variables, "moving" one element at a time
how much is added to the address depends on the size of the type to which the pointer points (as declared)
Recall arrays are contiguous memory What does this function do?
int mystery(int array[]) { int *p = &(array[0]); int sum = 0; while (*p != -1) { sum += *p; p++; } return sum; }
11 22 5 -1 2394 45346
30
#'$
!"!!"##$
#($
!"!!"##$
Pointer arithmetic
With two pointers in the same array, we can determine how far apart they are
size_t strlen(const char *str) { const char *ptr; for (ptr = str; *ptr; ptr++) ; return (size_t) (ptr str); } h e l l o
str
\0 ptr
33
#)$
!"!!"##$
35
#*$
2/22/11
int *nump;
declares a pointer, doesn't allocate anything more than space to store an address, connects the name nump to that space nump can be changed and assigned to
14
2/22/11
Arrays of pointers
We can also have an array of pointers:
int *nums[60]; an array of 60 pointers to int
2/22/11
An array of pointers
char *arg_vector[] = { arg_vector "prog", 1056 prog\0....... 1056 "1", 1192 1\0.......... 1192 "two", 1324 THREE\0...... 1584 "THREE", 1584 two\0........ 1324 "-4", 1776 -4\0......... 1776 0 NULL }; argv looks just like this, including the NULL at the end
17
Output:
13 3 8 6 6 6 8 ?????
18
2/24/11
11
Heap memory
can be allocated and deallocated in any order while the program is running
CMSC 216 - Wood, Sussman, Herman 12
2/24/11
user-managed heap
programmer can control the precise time to deallocate objects requires a lot more care - errors can occur if the wrong thing is freed, or the right thing is freed at the wrong time
13
both return NULL if the allocation fails both require #include <stdlib.h> since prototypes are contained there
2/24/11
15
16
!"#"$$%
Pointer aliases
We can have two pointers pointing to the same address Remember freeing the space doesnt change the value of the pointer or the value of the space pointed at
int *p, *q; p = malloc(sizeof(int)); *p = 99; q = p; /*values of p and q and *p and *q*/ free(p); p = NULL; *q = 42;
&%
!"#"$$%
Common errors
Dereferencing pointers to freed space (directly or indirectly) Forgetting to check the return value from malloc() for NULL Not initializing the memory malloc() returns Not allocating enough space:
char string[] = "Inconceivable!"; char *p = malloc(strlen(string)); strcpy(p, string); /* Oops... */
CMSC 216 - Wood, Sussman, Herman, Plane 5
!%
!"#"$$%
'%
!"#"$$%
Reallocation
If you need more space than you originally allocated, you could handle this yourself:
allocate array twice as large copy everything over free original array
But, there's a way to do this without nearly as much work on your part
10
(%
!"#"$$%
Reallocation, cont.
void *realloc(void *p, size_t new_size);
11
Use of realloc()
Often, you'll see this:
ptr = realloc(ptr, size * 2);
But what happens if the allocation fails? You can only do this if you know for certain you're going to exit the program on an allocation failure
12
)%
!"#"$$%
Both copy n bytes from the memory starting at src to the memory starting at dst, and return the dst pointer memcpy() cannot be used on overlapping arrays, though; but it's faster than memmove() Both prototypes contained in string.h
CMSC 216 - Wood, Sussman, Herman, Plane 13
*%