pointers introduction to systems programming - comp 1002, 1402

44
POINTERS Introduction to Systems Programming - COMP 1002, 1402

Upload: rosaline-chapman

Post on 06-Jan-2018

234 views

Category:

Documents


2 download

DESCRIPTION

Memory Allocation  When you declare a variable, some memory is allocated to store the value of the variable.  When you declare a global variable, the memory that is allocated for the global variable is permanent throughout the program.  When you declare a local variable inside a function, then the memory allocated for the local variable exists in a part of memory called the “stack”, and it exists only for as long as the function is being called. Same for parameters to a function.

TRANSCRIPT

Page 1: POINTERS Introduction to Systems Programming - COMP 1002, 1402

POINTERS

Introduction to Systems Programming - COMP 1002, 1402

Page 2: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Outline Memory Allocation Pointers in C Pointer and addresses Pointer Arithmetic Dynamic Memory Allocation

Page 3: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Memory Allocation When you declare a variable, some

memory is allocated to store the value of the variable.

When you declare a global variable, the memory that is allocated for the global variable is permanent throughout the program.

When you declare a local variable inside a function, then the memory allocated for the local variable exists in a part of memory called the “stack”, and it exists only for as long as the function is being called. Same for parameters to a function.

Page 4: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Pointers and Addresses C allows you to get the address of a variable. C has a type called “pointer” that points to

another type, such as int, unsigned char, float etc.

So, in C, there is an “int pointer”, “unsigned char pointer” etc.

A pointer to an integer is used to contain the address of an integer.

int n; // declare an integer variable called nint * iptr; // declare a variable called iptr // this variable is a pointer to an integer

void func() { iptr = &n; // set the value of iptr to the address of variable n}

Page 5: POINTERS Introduction to Systems Programming - COMP 1002, 1402

5

Declaring Pointers in C int *p; — a pointer to an int double *q; — a pointer to a double char **r; — a pointer to a pointer to

achar

type *s; — a pointer to an object of

type type E.g, a struct, union, function, something defined by

a typedef, etc.

Page 6: POINTERS Introduction to Systems Programming - COMP 1002, 1402

6

Declaring Pointers in C (continued) Pointer declarations:–read from right to

left const int *p;

p is a pointer to an integer constant I.e., pointer can change, thing it points to

cannot int * const q;

q is a constant pointer to an integer variable I.e., pointer cannot change, thing it points to

can! const int * const r;

r is a constant pointer to an integer constant

Page 7: POINTERS Introduction to Systems Programming - COMP 1002, 1402

7

Pointers in C Used everywhere

For building useful, interesting, data structures For returning data from functions For managing arrays

'&' unary operator generates a pointer to x E.g., scanf("%d", &x); E.g., p = &c; Operand of '&' must be an l-value — i.e., a legal object on

left of assignment operator ('=') Unary '*' operator dereferences a pointer

i.e., gets value pointed to E.g. *p refers to value of c (above) E.g., *p = x + y; *p = *q;

Not the same as binary '&'

operator (bitwise AND)

Page 8: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Pointer and Address Example

Here, we show the address and content of the variables n and iptr as they are declared.

After calling the function, the content at Address 101 will be the value 100.

int n = 20; // declare an integer variable called nint * iptr = 0; // declare a variable called iptr // this variable is a pointer to an integer

void func() { iptr = &n; // set the value of iptr to the address of variable n}

Variable Address Contentn 100 20iptr 101 0 100

Page 9: POINTERS Introduction to Systems Programming - COMP 1002, 1402

The & Operator As you saw in the preceding slide, the &

operator is used to get the address of a variable.

Here are some more examples.

int n = 20;int * iptr = 0;float f = 1.05;float * fptr = &f;

void func() { iptr = &n; // set the value of iptr to the address of variable n}

Variable Address Contentn 100 20iptr 101 0 100f 102 1.05fptr 103 102

Page 10: POINTERS Introduction to Systems Programming - COMP 1002, 1402

The * Operator: Dereferencing a Pointer

You can get the contents of what the pointer is pointing to by dereferencing a pointer.

int n = 20;int * iptr = 0;int i;

void func() { iptr = &n; i = *iptr + 50; }

Page 11: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Exercise: What gets printed?

#include <stdio.h>

int n = 20;float f = 1.05;float * fptr = &f;int * iptr = 0;int i;

int main() {iptr = &n;printf("addresses %d %d\n", iptr, fptr);printf("values %d %f\n", *iptr, *fptr);i = *iptr + 50;*iptr = 10;printf("values %d %d\n", n, i);return 0;

}

Address200201202203204

Page 12: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Dereferencing Pointer Dereferencing pointer actually refers to the

contents of what the pointer is pointing to. This doesn’t simply refer to the value. Hence, the content can be changed!

#include <stdio.h>

int n = 20;int * iptr = 0;

int main() { iptr = &n; *iptr = 10; printf("values %d\n", n); return 0;}

Page 13: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Call by Pointer Contrast the following

functions One is call by value, the

other is call by pointer. What exactly happens

when those functions are called?

#include <stdio.h>

int n = 20;

void func1(int i) { i = i + 10;}

void func2(int *r) { *r = *r + 20;}

int main() {

func1(n); printf(“n is %d\n", n);

func2(&n); printf(“n is %d\n", n); return 0;}

Page 14: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Can pointer refer to invalid address?

Yes, you can set pointer to any value you want.

But, if you set it to some reserved address, then the program will crash when you’re trying to refer to the reserved address.int i;int *iptr;

int main() { iptr = (int *)500; i = *iptr + 50;}

Set to invalid address 500 (probably reserved by the operating system)

Program crashes when trying to reference invalid address.

Page 15: POINTERS Introduction to Systems Programming - COMP 1002, 1402

15

Pointer Arithmetic int *p, *q;q = p + 1; Construct a pointer to the next integer after *p and assign it to q

double *p, *r;int n;r = p + n; Construct a pointer to a double that is n

doubles beyond *p, and assign it to r n may be negative

Page 16: POINTERS Introduction to Systems Programming - COMP 1002, 1402

16

Pointer Arithmetic (continued)

long int *p, *q;p++; q--; Increment p to point to the next long int;

decrement q to point to the previous long int

float *p, *q;int n;n = p – q; n is the number of floats between *p and *q; i.e., what would be added to q to get p

Page 17: POINTERS Introduction to Systems Programming - COMP 1002, 1402

17

Pointer Arithmetic (continued)

long int *p, *q;p++; q--; Increment p to point to the next long int;

decrement q to point to the previous long int

float *p, *q;int n;n = p – q; n is the number of floats between *p and *q; i.e., what would be added to q to get p

C never checks that the

resulting pointer is valid

Page 18: POINTERS Introduction to Systems Programming - COMP 1002, 1402

The “new” function

Refer to the highlighted line above. The “new” function does the following:

Allocate memory in the part of memory called “heap”. The amount of memory allocated is the amount needed to contain one integer.

The content of the memory location is set to the integer 15.

“new” returns the address of the memory that has just been allocated.

void func( ) { int *iptr; iptr = new int(15);}

Page 19: POINTERS Introduction to Systems Programming - COMP 1002, 1402

The “delete” function The “delete” function frees the memory

that has been created by “new”. Traditionally, C uses the functions “malloc”

and “free”, but I don’t like them. These days, we use the functions “new” and “delete” because they are cleaner.

void func( ) { int *iptr; iptr = new int(15); delete iptr; iptr = new int(20);}

Page 20: POINTERS Introduction to Systems Programming - COMP 1002, 1402

malloc and free

malloc requests some memory from the Operation System and returns the address of the memory allocated.

free frees up the space previously received by malloc.

void * malloc ( size_t size ); void free ( void * ptr );

void func(int n) { int i; int *iptr; iptr = (int *)malloc(n*sizeof(int)); for (i=0;i<n;i++) { iptr[i] = 15 + i * 2; } free(iptr);}

Page 21: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Pointer Example Program:Normalize (Part 1)

Example: The normalize function to normalize a vector

Mathematical background: Given a 3D vector V = (x,y,z), the magnitude of the vector V is sqrt(x*x+y*y+z*z)

Normalizing a vector means to make the vector the same direction as before, but with unit length (that is, the magnitude of the normalized vector should be 1).void Normalize(float *x, float *y, float *z) {

float mag; mag = (*x) * (*x) + (*y) * (*y) + (*z) * (*z); mag = sqrt(mag); // at the beginning of source file, need “#include <math.h>” // to use the function sqrt *x = (*x) / mag; *y = (*y) / mag; *z = (*z) / mag;}

Page 22: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Pointer Example Program:Normalize (Part 2)

Here, we use the Normalize function to change the values of a, b, c.

The Normalize function can be used to change the values of other variables.

This is a good use of pointers as parameters, because they can change the values of the contents they refer to.

int main() { float a, b, c; a = 10.0; b = 20.0; c = 15.0;

Normalize(&a, &b, &c); printf(“vector is %f %f %f\n”, a, b, c); return 0;}

Page 23: POINTERS Introduction to Systems Programming - COMP 1002, 1402

The NULL Pointer malloc returns the address of the memory that has been

allocated. However, sometimes it fails. For example, when the heap is full, or when malloc requests

too much memory, the OS cannot give malloc the memory. In this case, the return value of malloc is the NULL pointer.void func(int n) { int i; int *iptr; iptr = (int *)malloc(n*sizeof(int)); if (iptr != 0) { // check that malloc did not return the NULL pointer for (i=0;i<n;i++) { iptr[i] = 15 + i * 2; } free(iptr); }}

Page 24: POINTERS Introduction to Systems Programming - COMP 1002, 1402

24

What is the relationship between array and pointer? Arrays and pointers are closely related in

C In fact, they are essentially the same thing! Esp. when used as parameters of functions

int A[10];int *p; Type of A is int * p = A; and A = p; are legal assignments *p refers to A[0]*(p + n) refers to A[n]

p = &A[5]; is the same as p = A + 5;

Page 25: POINTERS Introduction to Systems Programming - COMP 1002, 1402

25

Arrays and Pointers (continued)

double A[10]; vs. double *A; Only difference:–

double A[10] sets aside ten units of memory, each large enough to hold a double, and A is initialized to point to the zeroth unit.

double *A sets aside one pointer-sized unit of memory, not initialized You are expected to come up with the memory elsewhere!

Note:– all pointer variables are the same size in any given machine architecture Regardless of what types they point to

Page 26: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Array and Address When you declare an array, the name of

the array also refers to the address of its first element.

In the following example, the value of “n” is the same as the value of “&(n[0])”

int n[20]; // declare an array of 20 integers

void func() { if (n==&(n[0])) { printf(“they are the same\n”); }}

Page 27: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Array and Pointer Since the name of an array is the same as

an address, and a pointer is also the same as an address, a pointer can be set to an array.

However, do not set array to pointer.int n[20]; // declare an array of 20 integersint *iptr;

void func() { iptr = n; // set pointer to array n[0] = 5; printf(“%d”, *iptr); // n = iptr; // do not set array to pointer}

Page 28: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Treating Pointer as Arrayint n[20]; // declare an array of 20 integersint *iptr;

void func() {

iptr = n; // set pointer to array

for (i=0;i<20;i++) { iptr[i] = 5; // treat pointer as array }

for (i=0;i<20;i++) { printf(“%d “, n[i]); }

}

Page 29: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Example: Averagefloat fg[80];float GetAverage(float *marray, int len) { int i; float sum; sum = 0; for (i=0;i<len;i++) {

sum += marray[i]; } return sum/(float)len;}

int main( ) { float f1[120]; float f2[60]; float a, b, c; … // some code to set the values of f1, f2 and fg a = GetAverage(f1,120); b = GetAverage(f2,60); c = GetAverage(fg,80); return 0;}

Page 30: POINTERS Introduction to Systems Programming - COMP 1002, 1402

new and delete for Arrays We learned that new can be used to

allocate space for an int, float etc. We learned that delete is used to free the

space. Now, new can be used to allocate an entire

array, and delete is used to free the entire array. void func() {

int *iptr; iptr = new int[20]; delete [ ] iptr;}

Page 31: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Example: Creating a new array

// print 1! up to n! 2000 timesvoid printFactorials(int n) {

int *iptr; int i, j;

iptr = new int[n]; // create an array of length n

iptr[0] = 1; for (i=1;i<n;i++) { iptr[i] = iptr[i-1] * (i+1); // set each element of the array } for (i=0;i<2000;i++) { for (j=0;j<n;j++) { printf(“%d “, iptr[j]); } printf(“\n”); }

delete [ ] iptr; // free the memory}

Page 32: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Exercise: Delete Duplicates Write a function DeleteDuplicates This function receives an array arr as an argument, and an integer len,

that tells the length of the array. The array received an argument has been allocated by new. The argument array contains floating point numbers in non-decreasing

order. DeleteDuplicates should create a new array, except that this array

should contain no duplicates. DeleteDuplicates should return the address of this new array. DeleteDuplicates should free the memory used by the old array. The length of the new array is set in nlen.

float *DeleteDuplicates(float *arr, int len, int *nlen); // function declaration

void func() { // example of use float *eptr; int nlen; eptr = new float[5]; eptr[0] = 1.0; eptr[1] = 1.6; eptr[2] = 1.6; eptr[3] = 2.3; eptr[4] = 2.3; eptr = DeleteDuplicates(eptr,5, &nlen);}

Page 33: POINTERS Introduction to Systems Programming - COMP 1002, 1402

33

Note C does not assign arrays to each other E.g,

double A[10];double B[10];

A = B; assigns the pointer value B to the pointer value A

Original contents of array A are untouched (and possibly unreachable!)

Page 34: POINTERS Introduction to Systems Programming - COMP 1002, 1402

34

Arrays as Function Parameters void init(float A[], int arraySize);void init(float *A, int arraySize);

Are identical function prototypes! Pointer is passed by value I.e. caller copies the value of a pointer to float into the parameter A

Called function can reference through that pointer to reach thing pointed to

Page 35: POINTERS Introduction to Systems Programming - COMP 1002, 1402

35

Arrays as Function Parameters (continued)

void init(float A[], int arraySize){int n;

for(n = 0; n < arraySize; n++)A[n] = (float)n;

} //init

Assigns values to the array A in place So that caller can see the changes!

Page 36: POINTERS Introduction to Systems Programming - COMP 1002, 1402

36

Exampleswhile ((rc = scanf("%lf", &array[count])) !=EOF && rc!=0)…

double getLargest(const double A[], const int sizeA) {double d;if (sizeA > 0) {d = getLargest(&A[1], sizeA-1);return (d > A[0]) ? d : A[0];} elsereturn A[0];

} // getLargest

Page 37: POINTERS Introduction to Systems Programming - COMP 1002, 1402

37

Result Even though all arguments are passed

by value to functions … … pointers allow functions to assign

back to data of caller

Page 38: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Exercise: Reverse There is an array of integers int a[100]; Assume that the array contains some numbers. Reverse the array. In other words, after you run your code,

the first element should contain the last element, and vice versa. And, the second element should contain the next to last element etc.

int a[100];

int main() {

}

Fill in code here

Page 39: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Exercise: Change Write a function CalculateChange(int m)

that prints the change for a money value.

For example CalculateChange(115) should print “25 25 25 25 10 5”

The valid coin values are 1, 5, 10 and 25.

Page 40: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Review: Pointers What does the following program print?

#include <stdio.h>

int main() { int i, j; int *iptr;

i = 256;

iptr = &i; printf(“%d “, (int)iptr);

printf(“%d “, *iptr);

iptr = (int *)i; printf(“%d “, (int)iptr);

return 0;

}

Variable Address Contenti 1000 ?j 1001 ?iptr 5000 ?

Memory:

Page 41: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Review: Pointers Which line(s) may cause compile time

error?#include <stdio.h>

int main() { int i, j; int *iptr;

i = 256; iptr = 512; iptr = &i;

iptr = (int *)i; *iptr = 20;

j = iptr; j = &iptr; j = (int) &iptr;

&i = iptr;

return 0;}

Answer of previous page:

1000 256 256

01234567891011121314151617181920

Page 42: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Review: Pointers Which line(s) may cause the program to

crash at run-time?#include <stdio.h>

int main() { int i, j; int *iptr; int *jptr;

i = 256; iptr = (int *)512;

jptr = iptr;

i = *iptr + 10;

iptr = (int *)i; *iptr = 20;

return 0;}

012345678910111213141516171819

Answer of previous page:Lines 7, 13, 14 and 17

Page 43: POINTERS Introduction to Systems Programming - COMP 1002, 1402

Review: new and delete Which line(s) may cause compile time error? Which line(s) may cause program to crash at run time?

#include <stdio.h>

int main() { int i; int *iptr;

i = 10;

iptr = new int(5); *iptr = 20;

delete iptr; *iptr = 15; iptr = &i;

delete iptr;

return 0;}

012345678910111213141516171819

Answer of previous page:Lines 12 and 15

Answer :Line 13 may cause a problem because you write to memory that has been freed.Line 16 has an error because you try to free memory from the stack, i.e. not created by new.

Page 44: POINTERS Introduction to Systems Programming - COMP 1002, 1402

44

QUESTIONS?