Вы находитесь на странице: 1из 17

CPSC 211 (Data Structures & Implementations)

Pointers in C Pointer is a variable (data object) which has as a value an address of another variable.
P 12333 12333 (address)
Variable of type Object Type

Pointers are used to: create more complex data types as lists, queues, stacks or trees. pass complex structures to a function (it corresponds to calling by reference which does not exist in C). process arrays. return structured variables from a function (call by reference). return an allocated block of memory.
Slide 2.1

CPSC 211 (Data Structures & Implementations)

To dene a pointer variable we use the same rules as dening an ordinary variable. The only difference is that the asterisk is added in front of the name of the pointer variable.
int i = 1; /* allocates space for integer i and
returns address to the integer */ int *iptr; /* allocates space for a pointer to an integer */ iptr = &i; /* address of iptr is the same as address of i */ *iptr = 2; /* stores a value (2) for a variable pointed by iptr */ *iptr = *iptr + 1; /* the new value is 3 */

&i is the address-of operator. The asterisk in *ptr is also called dereferencing (or indirection) operator.

Slide 2.2

CPSC 211 (Data Structures & Implementations)

Pointers can point to nothing (NULL) or allocate storage by using malloc or calloc functions:
typedef struct Student int ID double GPA; Student P = (Student *) malloc(sizeof(Student));

Before P
??

After Allocate memory for an object


?? ??

P After

Before
ID ?? G ??

ID

P Before
ID G

Set values

12

5.5

P After

12

5.5

Free object

P
??

P->ID = 12; P->GPA = 3.5; /* initialize */ free(P); /* release memory */


Slide 2.3

CPSC 211 (Data Structures & Implementations)

Computer memory is a one-dimensional array of bytes. Each variable is stored in a sequence of bytes. The address of a variable is the address of the rst byte in the array of bytes. Let *ptr = num. Then iptr value 1232 refers to the location of the integer variable num and *iptr has the value .

128 1232 int *iptr ...

1232 2 int num ...

address data variable type

Slide 2.4

CPSC 211 (Data Structures & Implementations)

Examples Consider the block of storage referenced by int pointers pa and pb. The assignments: *pa = 5; and *pb = 10; are correct. But the instruction pa = 17 is incorrect because there is mismatch of types (type pointer to int and int are not the same). The instruction *pa = *pb copies the value in the storage pointed by pb to the storage pointed by pa. If we have pa = pb; then both the pointer variables reference to in this case). They are called aliases. the same storage (which contains The block of storage such that no pointer references to it becomes inaccessible. The function free(pa); returns the block of storage referenced by pa to the pool of available storage. In C, there is no automatic garbage collection. Recycling of storage must be managed by the programmer. If we have the situation: pa = pb; and free(pb); then pa is a dangling pointer, that is, a pointer which references to an inaccessible block of storage. This is a source of difcult-to-nd bugs.
Slide 2.5

CPSC 211 (Data Structures & Implementations)

Indirection and Address-Of Operators Indirection: * is applied only to a pointer variable, to refer the location whose address is held by the pointer variable. Address-of: & can be applied to non-pointer and pointer variables.
int *iptr; int i = 2; *iptr = 17; /* correct */ iptr = &i; /* correct */ iptr = &17; /* wrong, you cant apply & to a literal (number) */ i = iptr; /* wrong, incompatible types */ i = *iptr; /* correct */ iptr = i; /* wrong, incompatible types */

Slide 2.6

CPSC 211 (Data Structures & Implementations)

Passing Pointer Variables as Parameters We can use pointers as formal parameters of a function.
void printID(Student *sr) printf("Student ID is %d n", sr->ID);

Example 1. We can call the function printID as follows:


Student sr = 67890, 3.4 ; printID(&sr); /* & is necessary here */

Example 2. This is another way:


Student *sr; /* not initialized */ sr = (Student *) malloc(sizeof(Student)); sr->ID = 67890; sr->GPA = 3.4; printID(sr);

Slide 2.7

CPSC 211 (Data Structures & Implementations)

Passing Parameters to a Function In C, call by value is the only way to pass parameters to a function. But when a pointer to a variable is used as a formal parameter and then this variable is changed inside the function then it is also changed in the actual parameter. Example:
void swap(int a, int b) int temp = a; a = b; temp = a;

A space for the variables a, b, temp is allocated statically in this function and this space is automatically released after its execution. Therefore, if you call
int a = 2, b = 3; swap(a, b);

the swap function does not swap the values of a and b.


Slide 2.8

CPSC 211 (Data Structures & Implementations)

To use swap correctly you must use another approach.


void swap(int *a, int *b)

int temp; temp = *a; *a = *b; temp = *a;

int main()

int a = 2, b = 3; printf("before: a = %d, b = %d n", a, b); swap(&a, &b); /* & is necessary here */ printf("after: a = %d, b = %d n", a, b);

Slide 2.9

CPSC 211 (Data Structures & Implementations)

Memory Allocation To allocate memory dynamically the function malloc is used. It returns a generic pointer of type void*. In order to obtain a correct type we must change the generic pointer type to a type we need using a cast (for instance, (int*)). The obtained pointer indicates the beginning of the allocated space. If malloc fails to allocate memory it returns NULL.
int *a; a = (int *) malloc(sizeof(int)); printf("malloc failed n"); if (a == NULL) *a = 120;

Usually, we do not allocate space for variables of primitive type at run time. Typically, malloc is used to allocate space for a structure or an array.

Slide 2.10

CPSC 211 (Data Structures & Implementations)

Examples
struct int ID; double GPA; /* grade */ Student; Student *sptr; sptr = (Student *) malloc(sizeof(Student)); sptr->ID = 2310; sptr->GPA = 3.4;

typedef

To allocate an array dynamically, we multiply sizeof(type) by the required number of elements of the array.
int i; Student *p; /* p is an array */ p = (Student *) malloc(35*sizeof(Student)); for (i = 0; i < 35; i++) p[i].ID = 120 + i; p[i].GPA = 0.0;

Slide 2.11

CPSC 211 (Data Structures & Implementations)

Memory Deallocation The allocated memory remains in use until the program has nished or memory is released using the function free. Example of a memory leak:
void section() Student *p; p = (Student *) malloc(35*sizeof(Student)); return; /* wrong! */

After executing the function section the pointer p is removed from the stack but the allocated memory is not released and it cannot be accessed. To access the array outside section a pointer to an array must be returned.
Student *section() Student *p; p = (Student *) malloc(35*sizeof(Student)); return p;

Slide 2.12

CPSC 211 (Data Structures & Implementations)

Operations on Pointers &i *p p++ ++p address of a referenced location contents of a referenced location value of the pointer p incremented by one unit of base type size (p = p + sizeof(base type)) increments the pointer p = p + sizeof(base type) then gets the value of p assigns a memory location to the pointer declares a pointer and its base type gets a value of *p then increment p

p = &i type *p

*(p++) or *p++ (*p)++

is not equivalent to *p++ preincrements p, then gets the value

*(++p) or *++p ++(*p)

increments the value pointed to by p


Slide 2.13

CPSC 211 (Data Structures & Implementations)

Arrays A pointer can be treated as just a memory address of a block of storage. But this interpretation of a pointer is not always useful, and we will treat pointers in a more abstract way. A very useful interpretation is to see a pointer as a generalization of an index of a vector (array). Especially in C you can easily notice this relation between pointers and vector indices.
double A[100]; /* elements start from 0, that is, A[0],A[1],...,A[99] */ double *pa = &A[3]; /* pa points to the 4th element of A */ double *pa1 = &A[5]; /* the same can be done as follows: */ pa = A + 3; /* pointer arithmetic is involved here! */ /* here we get that the distance between pa1 and pa is 2 = 5-3 */ printf("distance between pointers pa" " and pa1 is = %d n", pa1 - pa);

Slide 2.14

CPSC 211 (Data Structures & Implementations)

The name of an array is a pointer to the rst element of the array. The array name is a constant pointer, it cannot be changed by performing pointer arithmetic. Note that C compiler does not check bounds of an array. There is no pointer arithmetics in Pascal and Java. In languages where pointers are unavailable (as for instance Fortran77) we can still use vector indices to emulate pointers but we lose their dynamical feature (the possibility of changing the size of a data structure during runtime).

Slide 2.15

CPSC 211 (Data Structures & Implementations)

More about Pointers Pointers are very useful in dynamically created data structures. They are used in many data structures we are going to discuss (for instance, in linked representations of data structures).
typedef struct int ID; double GPA; Student; int main() Student *P, *Q; P = (Student *) malloc(sizeof(Student)); P->ID = 99999999; P->GPA = 3.4; Q = P; /* Q is an alias */ ... free(P); /* deallocate memory pointed by P */ P = Q = NULL; /* otherwise P and Q are dangling pointers */ ...

Slide 2.16

CPSC 211 (Data Structures & Implementations)

An address is always a positive integer. Therefore the address 0 represents a special value meaning that no address is available. Often this 0 is denoted by NULL.

Slide 2.17

Вам также может понравиться