Presentation is loading. Please wait.

Presentation is loading. Please wait.

Pointers. Why pointers? - low-level, but efficient manipulation of memory - dynamic objects  Objects whose memory is allocated during program execution.

Similar presentations


Presentation on theme: "Pointers. Why pointers? - low-level, but efficient manipulation of memory - dynamic objects  Objects whose memory is allocated during program execution."— Presentation transcript:

1 Pointers

2 Why pointers? - low-level, but efficient manipulation of memory - dynamic objects  Objects whose memory is allocated during program execution. ( Dynamic objects can survive after the function ends in which they were allocated).  Dynamic objects allow flexible-sized arrays and lists

3 Pointers  A pointer is a variable used for storing the address of a memory cell.  We can use the pointer to reference this memory cell, so to ‘manipulate’ it! 100 ……1024… Memory address:1024 10032 … 1020 Integer a Pointer p n Object whose value represents the location (memory address) of another object int a; int* p;

4 Getting an address: address operator & int a=100; “&a”  “the address of a” 100………… Memory address:1024 int a = 100; cout << a;  100 Cout << &a;  1024 … 1020 a

5 Define a pointer type variable: T* Examples of (uninitialized) pointers int* ip; char* s; int *ip; // ip is a pointer to an int char *s; // s is a pointer to a char TypeName *variablename; int *p; Each type of object (variable) has a pointer type, therefore a pointer variable of that type. TypeName* variablename; int* p; equivalent

6 Store the address in a pointer variable  The value of pointer p is the address of variable a 10088…1024… Memory address:102410032 … 1020 ap int a = 100; int* p = &a; cout << a << " " << &a <<endl; cout << p << " " << &p <<endl; Result is: 100 1024 1024 10032 p is pointing to a  A pointer is also a variable, so it has its own memory address

7 Dereferencing Operator *  We can access to the value stored in the variable pointed to by preceding the pointer with the “star” operator (*), 10088…1024… Memory address:102410032 … 1020 int a = 100; int* p = &a; cout << a << endl; cout << &a << endl; cout << p << " " << *p << endl; cout << &p << endl; a p *p gives 100

8 An asterisk (‘*’) has two usages  In a definition, an asterisk indicates that the object is a pointer. char* s; // s is of type pointer to char (char *s; is possible)  In expressions, an asterisk before a pointer indicates the object the pointer pointed to, called dereferencing int i = 1, j; int* ptr; // ptr is an int pointer ptr = &i; // ptr points to i j = *ptr + 1;// j is assigned 2 cout << *ptr << j << endl; // display " 12 "

9 Summary on two operators * and & * has two usages: - pointer - dereferencing & has two usages: - getting address - reference (‘call by ref’, see later)

10 Null Address  0 is a pointer constant that represents the empty or null address  Indicates that pointer is not pointing to storage of a valid object  Cannot dereference a pointer whose value is null int* ptr; ptr = 0; cout << *ptr << endl; // invalid, ptr // does not point to // a valid int

11 Example #include using namespace std; int main (){ int value1 = 5, value2 = 15; int* p1; int* p2; p1 = &value1; // p1 = address of value1 p2 = &value2; // p2 = address of value2 *p1 = 10; // value pointed to by p1=10 *p2 = *p1; // value pointed to by p2= value // pointed to by p1 p1 = p2; // p1 = p2 (pointer value copied) *p1 = 20; // value pointed to by p1 = 20 cout << "value1==" << value1 << "/ value2==" << value2; return 0; } Result: Value1 is 10 Value2 is 20

12 Another Pointer Example int a = 3; char s = ‘z’; double d = 1.03; int* pa = &a; char* ps = &s; double* pd = &d; cout << sizeof(pa) << sizeof(*pa) << sizeof(&pa) << endl; cout << sizeof(ps) << sizeof(*ps) << sizeof(&ps) << endl; cout << sizeof(pd) << sizeof(*pd) << sizeof(&pd) << endl;

13 Writing pointer type properly in C++ … int *a, *b; a, b are both integer pointers int* a, b; a is integer pointer, b is just integer! typedef int* IntPt; IntPt a, b; typedef int MyInt; MyInt k; int k; int* a; int* b; ? Recommended:

14 Traditional Pointer Usage void swap(char* ptr1, char* ptr2){ char temp = *ptr1; *ptr1 = *ptr2; *ptr2 = temp; } int main() { char a = 'y'; char b = 'n'; swap(&a, &b); cout << a << b << endl; return 0; } Use pass-by-value of pointers to ‘change’ variable values C language does not have ‘call by reference’, only ‘call by value’!

15 Reference: T& l int& b a; l b is an alternative name for a void f(int& b) {}; int main() { int a; f(a); }

16 Pass by reference (better than ‘pointers’) void swap(char& y, char& z) { char temp = y; y = z; z = temp; } int main() { char a = 'y'; char b = 'n'; swap(a, b); cout << a << b << endl; return 0; } y, z are ‘references’, only names, not like ptr1, ptr2 that are variables

17 Pointer to ‘Struct’ struct Date {…}; Date d={1,10,2009}; Date* pd = &d; (*pd).day=2; (*pd).month=11; Or pd->day=2; pd->month=11;

18 Pointers and arrays

19 Arrays are pointers! The name of an array points only to the first element not the whole array. 1000 1012 1016 1004 1008

20 #include Using namespace std; void main (){ // Demonstrate array name is a pointer constant int a[5]; cout << "Address of a[0]: " << &a[0] << endl << "Name as pointer: " << a << endl; } /* result: Address of a[0]: 0x0065FDE4 Name as pointer: 0x0065FDE4 */ Array name is a pointer constant

21 Result is: 2 #include Using namespace std; void main(){ int a[5] = {2,4,6,8,22}; cout << *a << " " << a[0] << " " << *(&a[0]);..." } //main 2 4 8 6 22 a[4] a[0] a[2] a[1] a[3] Dereference of an array name This element is called a[0] or *a

22 To access an array, any pointer to the first element can be used instead of the name of the array. We could replace *p by *a #include Using namespace std; void main(){ int a[5] = {2,4,6,8,22}; int* p = a; int i = 0; cout << a[i] << " " << *p;... } 2 4 8 6 22 a[4] a[0] a[2] a[1] a[3] a p a Array name as pointer 2 2

23 Multiple Array Pointers Both a and p are pointers to the same array. 2 4 #include Using namespace std; void main(){ int a[5] = {2,4,6,8,22}; int* p = &a[1]; cout << a[0] << " " << p[-1]; cout << a[1] << " " << p[0];... } 2 4 8 6 22 a[4] a[0] a[2] a[1] a[3] p P[0] A[0]

24 Pointer Arithmetic Given a pointer p, p+n refers to the element that is offset from p by n positions. 2 4 8 6 22 a a + 2 a + 4 a + 3 a + 1 p p + 2 p + 3 p - 1 p + 1

25 *(a+n) is identical to a[n] Dereferencing Array Pointers a[3] or *(a + 3) 2 4 8 6 22 a a + 2 a + 4 a + 3 a + 1 a[2] or *(a + 2) a[1] or *(a + 1) a[0] or *(a + 0) a[4] or *(a + 4)

26 Summary * two usages: - pointer type definition: int a; int* p; - dereferencing: *p is an integer variable if p = &a; & two usages: - getting address: p = &a; - reference: int& b a; b is an alternative name for a First application in passing parameters (‘swap’ example) int a=10; int b=100; int* p; int* q; p=&a; q=&b; p = q; *p = *q; ? ?

27 a[n]: like a vector, an array a+n *(a+n): like a ‘sequence’ or a ‘list’ Two ways of manipulating an array ‘a’ points to the first element

28 Dynamic Objects

29 Memory Management  Static Memory Allocation  Memory is allocated at compiling time  Dynamic Memory  Memory is allocated at running time { int a[200]; … } { int n; cin >> n; a[n]??? }

30 Static vs. Dynamic Objects  Static object  Memory is acquired automatically  Memory is returned automatically when object goes out of scope  Dynamic object  Memory is acquired by program with an allocation request  new operation  Dynamic objects can exist beyond the function in which they were allocated  Object memory is returned by a deallocation request  delete operation

31 Creating a variable (object): new T Syntax ptr = new SomeType; where ptr is a pointer of type SomeType p Uninitialized int variable Example int* p = new int; ‘new’ does two things: 1. Create a variable of given type 2. Point the pointer p to the variable

32 Destructing a variable (object): delete p Syntax delete p; storage pointed to by p is returned to free store and p is now undefined Example int* p = new int; *p = 10; delete p; p 10 ‘delete’ does two things: 1. Return the pointed object to the system 2. Point the pointer p to NULL

33 Dynamic Arrays (a collection of variables)  Syntax for allocation: p = new SomeType[Expression];  Where  p is a pointer of type SomeType  Expression is the number of objects to be constructed -- we are making an array  Syntax for de-allocation: delete[] p;  Because of the flexible pointer syntax, p can be considered to be an array p = new T[size];delete[] p;

34 Example Dynamic Memory Allocation  Request for “ unnamed ” memory from the Operating System int* p, n=10; p = new int; p = new int[100]; p p p = new int[n]; p

35 Freeing (or deleting) Memory

36 Allocation Example Need an array of unknown size main() { int n; cout << “How many students? “; cin >> n; int* grades = new int[n]; for(int i=0; i < n; i++){ int mark; cout << “Input Grade for Student” << (i+1) << “ ? :”; cin >> mark; grades[i] = mark; }... printMean( grades, n ); // call a function with dynamic array... } int grades[n];

37 Dangling Pointer Problem int* A = new int[5]; for(int i=0; i<5; i++) A[i] = i; int* B = A; delete[] A; B[0] = 1; // illegal!

38 Memory Leak Problem int* A = new int[5]; for(int i=0; i<5; i++) A[i] = i; A = new int[5]; A 0 1 2 3 4 2

39 Static variables (objects)Dynamic variables (objects) A (direct) named memory locationA static part (pointer) + (indirect) nameless memory location (dynamic part) int a; a = 20; int* pa; pa = new int; *pa = 20; 20 a pa static dynamic Summary

40 int* p = new int; *p = 10; delete p; p 10 p int* p = new int[100]; for (i=1;i<100,i++) p[i] = 10; delete[] p; Simple dynamic variable Dynamic array ‘delete p’ is not sufficient for an array!!! ‘delete’ two actions: 1. Return the object pointed to 2. Point the pointer p to NULL 10

41 Good practice  Logically, Initialize a pointer with NULL  Always check a pointer before usage  if (p != NULL) *p

42 n=100; int* p = new int[n]; N=150; P[130]??? Bad examples { int n; cin >> n; a[n]??? } It’s possible, but not standard, Do: int* a = new int[n]; No! the array stays with the size 100.

43 More pointers

44 Pointers to pointers

45 Pointer to pointer: T** int a; int* p; int** q; a = 58; p = &a; q = &p; a pq 58 a, *p, and **q are the same object whose value is 58! But q = &a is illegal!

46 Pointer to pointers and 2D arrays

47 Pointer of pointers & 2D Arrays table[0] or *( table + 0 ) table[1] or *( table + 1 ) table[2] or *( table + 2 ) int table[3][4]; for(int i=0; i<3; i++){ for(int j=0; j<4; j++) cout << *(*(table+i) +j); cout << endl; } table[i][j]What is **table ? table + 2 table table + 1

48 table and table[0] are of the same address int table[2][2] = {{0,1}, {2,3}}; cout << table << endl; cout << *table << endl; //same as above cout << table[0] << endl; // same as above cout << *table[0] << endl; cout << table[0][0] << endl; // same as above cout << **table << end; // same as above 0xffbff938 0

49 Array of Pointers & Pointer to Array a b c An array of Pointers p int a = 1, b = 2, c = 3; int* p[5]; p[0] = &a; p[1] = &b; p[2] = &c; int list[5] = {9, 8, 7, 6, 5}; int* p; p = list;//points to 1 st entry p = &list[0];//points to 1 st entry p = &list[1];//points to 2 nd entry p = list + 1; //points to 2 nd entry A pointer to an array

50 A Dynamic Table  A dynamic table is an array of pointers to save space when not all rows of the array are full. int** table; table = new int*[6]; table[0] = new int[4]; table[1] = new int[7]; table[2] = new int[1]; table[3] = new int[3]; table[4] = new int[2]; table[5] = NULL; table[0] table[1] table[2] table[3] table[4] table[5] table

51 table[0][0] = 32; table[0][1] = 18; … 32182412 42141912161113 1811 131413 22 table[0] table[1] table[2] table[3] table[4] table[5] table *(*(table+i)+j) is table[i][j]

52 int m, n; cin >> m >> n >> endl; int** mat; mat = new int*[m]; for (int i=0;i<m;i++) mat[i] = new int[n]; Create a matrix of any dimensions, m by n: int main() { int m, n; cin >> m >> n >> endl; int** matrix; matrix = imatrix(m,n); … } int** imatrix(int m, int n) { int** mat; mat = new int*[m]; for (int i=0;i<n;i++) mat[i] = new int[n]; return mat; } Put it into a function:Ideas:

53  Each row must be deleted individually  Be careful to delete each row before deleting the table pointer. Dynamic matrix deallocation void deleteImatrix(int** mat, int m, int n) { for(int i=0; i<m; i++) delete[] mat[i]; delete[] mat; } for(int i=0; i<6; i++) delete[] mat[i]; delete[] mat;

54  ‘argc’ is the actual number of arguments  ‘argv’ is an array of char*, each pointing to a character int main()  int main(int argc, char* argv[]) E.g. a.out 20 30 int main(int argc, char* argv[]) { if (argc != 3) { troubles!!!} int rows = atoi(argv[1]); int col = atoi(argv[2]); } Examples: main() arguments

55 Constantness: object or pointer?

56 (const) object (*const) pointer  ‘const’ only modifies a type  const T* p  constant T, so constant object, const *p  ‘const’ only modifies a type as it might be one of them:  const T* p  T *const p  constant pointer  const T *const p  = constant pointer to constant object (both pointer AND object are constants!)  No ‘const*’ operator.

57 Example: 57 A constant object with ‘const’: const int* p; A constant pointer with ‘*const’: int *const p; A constant object AND pointer is: const int *const p;

58 ‘const object’ and ‘constant pointer’  Pointer to const object: the content is const, pointer is free  int x=10, y=20;  const int* pc = &x;  pc = &y // OK  *pc = 5; // wrong!  Const pointer: the pointer is const, content is free  int x=10, y=20;  Int *const cp = &x;  *cp = 5; // OK  cp = &y; // wrong!  int const *pc

59 59 void f1(const int** bar){ bar[1][1] = 5; // wrong: change int bar[1] = new int[3]; // ok } void f2(int *const *bar){ bar[1][1] = 5; // ok bar[1] = new int[3]; // wrong: change int* bar = new int*[3]; // ok } void f3(int **const bar) { bar[1][1] = 5; // ok bar[1]= new int[3]; // ok bar = new int*[3]; // wrong: change int** } int main(){ int** iptr; int i, j; iptr = new int*[10]; for( i = 0; i < 10; i++ ) iptr[i] = new int[10]; for( i = 0; i < 10; i++ ) for( j = 0; i < 10; i++ ) iptr[i][j] = i*j; f1(iptr); f2(iptr); f3(iptr); } Bad: const int ** bar Bad: int * const * bar Because of ambiguous ‘const int** b’ and ‘const int **b’, so it is ‘const int’! Writing properly matters!!!

60 More examples … 60 int main(){ int i = 3, j = 10; int* ip = &i; *ip = 4; const int* ipc = ip; *ip = 5; // *ipc is now 5 ip = &j; int *const *ipp1 = &ip; // ok const int* const *ipp2 = &ip; // ok const int** ipp3 = &ipc; // ok ipp3 = &ip; // wrong: changing ipp3 // indirectly/inadvertently changes **ipp const int** ipp4 = &ip; // wrong: same reason as above, because if allowed ipp4 //could be changed later return 0; }

61 Pointer to function

62 Function pointers  A running program and functions get a certain space in the main memory  To store the executable comiled codes and variables  A function name is an address pointing to the execution codes of the function  When the function is called, the codes and variables are loaded to the call stack  A function pointer is a pointer, which points to the address of the function  A function pointer can be passed as a parameter to a function  int const *pc

63 #include using namespace std; // put a and b in ascending order void ascending( double& a, double& b ){ if( a > b ){ double tmp = a; a = b; b = tmp; } return; } // put a and b in descending order void descending( double & a, double & b ){ if( a < b ){ double tmp = a; a = b; b = tmp; } return; } // function pointer void order( void (*criteria)(double &, double &), double & a, double & b) { (*criteria)(a, b); // same as criteria(a,b); return; } int main(){ double x = 0.7; double y = 0.5; order( ascending, x, y ); cout << x << " " << y << endl; order( descending, x, y ); cout << x << " " << y << endl; return 1; } 0.5 0.7 0.7 0.5 Output:


Download ppt "Pointers. Why pointers? - low-level, but efficient manipulation of memory - dynamic objects  Objects whose memory is allocated during program execution."

Similar presentations


Ads by Google