Presentation is loading. Please wait.

Presentation is loading. Please wait.

Pointers by Dr. Bun Yue Professor of Computer Science 2013 CSCI 3333 Data Structures.

Similar presentations


Presentation on theme: "Pointers by Dr. Bun Yue Professor of Computer Science 2013 CSCI 3333 Data Structures."— Presentation transcript:

1 Pointers by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu http://sce.uhcl.edu/yue/ 2013 yue@uhcl.edu http://sce.uhcl.edu/yue/ CSCI 3333 Data Structures

2 Acknowledgement  Mr. Charles Moen  Dr. Wei Ding  Ms. Krishani Abeysekera

3 Assumptions  Assume that you are familiar with C, C++ or Java.

4 Brief Facts About C++  Evolved from C  Designed and implemented by Bjarne Stroustrup at the Bell Labs in the early 1980s  “C with classes”, Better C  Standardized by ISO in 1997 Includes the C++ standard library Standard Template Library (STL)  Part of the C++ standard library  Ready made classes for data structures and algorithms

5 C++ Filenames  Can be different from the name of the class or the name of the function in the file .cpp Extension for the C++ source code files .h Extension for C++ header files Usually, code for a data structure is put in a header file, and then it can be added to a program with an include directive, e.g. #include "BasicVector.h"  Name of executable file In MSVS it’s the name of your project In g++ it’s either “ a.out ” or a name you specify

6 A Simple C++ Example /* FILE: main.cpp */ #include using namespace std; int main() { cout << "Enter your first name: "; string name; cin >> name; cout << "Hello, " << name << endl; return 0; //optional }

7 /* FILE: main.cpp */ #include using namespace std; int main() { cout << "Enter your first name: "; string name; cin >> name; cout << "Hello, " << name << endl; return 0; //optional } A Simple C++ Example Comment C++ header files from C++ standard library “Entry” function Namespace for C++ standard library All C++ statements end with a semicolon

8 Memory Address  Every byte in the primary memory has an address.  In C++, a pointer is a variable that stores a memory address.  The address (reference) operator & is used to return the address of a variable.

9 Pointer Type  A pointer variable has a type associated with it, and the memory address it points to should hold data of that type. int myInt = 0; // Allocates memory; stores 0 int *pMyInt; // Declares pointer variable without // initialization

10 An Example #include using namespace std; int main() { int x = 10; float y = 3.14159; string z = "I am a college professor."; bool b = true; cout << "x: value: " << x << " addr: " << &x << endl; cout << "y: value: " << y << " addr: " << &y << endl; cout << "z: value: " << z << " addr: " << &z << endl; cout << "b: value: " << b << " addr: " << &b << endl; }

11 Output x: value: 10 addr: 0012FF50 y: value: 3.14159 addr: 0012FF44 z: value: I am a college professor. addr: 0012FF1C b: value: 1 addr: 0012FF13

12 Pointer Type Checking  A pointer variable of a particular type cannot store address of an incompatible type. Error: int x = 10; float* fp_x = &x; MS VS: “Types pointed to are unrelated; conversion requires reinterpret_cast, C- style cast or function-style cast”

13 Dereferencing  Dereferencing (indirection) operation in C++: *. *p: access the value of the memory address stored in p.  * is heavy overloaded in C++: Number multiplication Pointer variable declaration Dereferencing.

14 Example … int main() { int x = 10; cout << "value of x = " << x << endl; int* p_x = &x; cout << "value of p_x = " << p_x << endl; int** p_p_x = &p_x; cout << "value of p_p_x = " << p_p_x << endl; int*** p_p_p_x = &p_p_x; cout << "value of p_p_p_x = " << p_p_p_x << endl; *p_x = 15; cout << "value of x = " << x << endl; }

15 Output of Example value of x = 10 value of p_x = 0012FF60 value of p_p_x = 0012FF54 value of p_p_p_x = 0012FF48 value of x = 15

16 Example // Dereferencing: cout << "value of *p_x = " << *p_x << endl; cout << "value of *p_p_x = " << *p_p_x << endl; cout << "value of **p_p_x = " << **p_p_x << endl; cout << "value of *p_p_p_x = " << *p_p_p_x << endl; cout << "value of **p_p_p_x = " << **p_p_p_x << endl; cout << "value of ***p_p_p_x = " << ***p_p_p_x << endl;

17 Output of Example value of *p_x = 10 value of *p_p_x = 0012FF60 value of **p_p_x = 10 value of *p_p_p_x = 0012FF54 value of **p_p_p_x = 0012FF60 value of ***p_p_p_x = 10

18 Example: Same Effect … int main() { int x = 10; cout << "value of x = " << x << endl; int* p_x = &x; cout << "value of p_x = " << p_x << endl; int** p_p_x = &p_x; cout << "value of p_p_x = " << p_p_x << endl; int*** p_p_p_x = &p_p_x; cout << "value of p_p_p_x = " << p_p_p_x << endl; ***p_p_p_x = 15; // Change from *p_x = 15; cout << "value of x = " << x << endl; }

19 Where are the errors? int main(){ int m; int *pm; *pm = 5; int n; int *pn = &n; pn = 5; }

20 Where are the errors? int main(){ int m; int *pm; *pm = 5; int n; int *pn = &n; pn = 5; } ERROR! No address in pm //Correction pm = &m; *pm = 5;

21 Where are the errors? int main(){ int m; int *pm; *pm = 5; int n; int *pn = &n; pn = 5; } ERROR! No address in pm //Correction pm = &m; *pm = 5; ERROR! Missing operator* //Correction *pn = 5;

22 Error messages For pn = 5; MS VS: “error C2440: '=' : cannot convert from 'int' to 'int *‘. Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast”

23 Error messages For int *pm; *pm = 5; MSVS: warning C4101: ‘pm' : unreferenced local variable; warning C4700: uninitialized local variable 'pm' used.

24 Error messages  Executing the program after comment out pn = 5; (thus no compilation error, just warnings).

25 Pointer and Array  A name of an array holds the address of the first element in the array.  Thus, an array is just a pointer const (cannot be changed).  This definition is different from the usual definition of array.  Pointers and arrays point to elements of the same type.

26 Example int a[5] = {1,2,3,4,5}; cout << "a[2] = " << a[2] << endl; cout << "a = " << a << endl; cout << "a+2 = " << (a+2) << endl; cout << "a+4 = " << (a+4) << endl; cout << "a+6 = " << (a+6) << endl; Output: a[2] = 3 a = 0012FF50 a+2 = 0012FF58 a+4 = 0012FF60 a+6 = 0012FF68

27 Example int a[5] = {1,2,3,4,5}; *(a+3) = 20; cout << " a[3] = " << a[3] << endl; Output: a[3] = 20

28 Example int a[5] = {1,2,3,4,5}; *(a+5) = 40; cout << "*(a+5) = " << *(a+5) << endl; Output: *(a+5) = 40

29 Pointer Arithmetic  C/C++ allow pointer arithmetic: + and – for pointer and array, ++ and -- for pointer.  If a and p are array and pointer respectively, the following operations are allowed: p++, p-- a-1, a+20, p+i*j, p-3*j

30 Example int a[5] = {1,2,3,4,5}; int *p; p = &a[1]; cout << a[0] << ", " << p[-1]<< ", " << *(p - 1) << endl; cout << a[1] << ", " <<p[0]<< ", " << *(p) << endl; cout << a[2] << ", " << p[1]<< ", " << *(p + 1) << endl; Output:  1, 1, 1  2, 2, 2  3, 3, 3

31 Example int b[5] = {12, 4, 16, 98, 50}; p = b; cout << (*p)++ << endl;// prints 12 cout << *p << endl;// prints 13 cout << *++p << endl;// prints 4 cout << *p << endl; // prints 4 cout << (*p)-- << endl; // prints 4 cout << *p << endl; // prints 3 cout << *--p << endl; // prints 13 cout << *p << endl; // prints 13

32 Pointer Operations  Operations are adjusted with respect to the location of the element.  Thus, p++ update p to point to the next element, no matter what the type of the element is.

33 Example double d[5] = {1.0, 3.0, 5.0, 7.0}; cout << "d[2] = " << d[2] << endl; cout << "d = " << (d) << endl; cout << "d+1 = " << (d+1) << endl; cout << "d+2 = " << (d+2) << endl; cout << "d+3 = " << (d+3) << endl; Output: d[2] = 5 d = 0012FEE4 d+1 = 0012FEEC d+2 = 0012FEF4 d+3 = 0012FEFC

34 Why Pointer Arithmetic  Efficiency!

35 Example: strcpy char *strcpy (char *dst, const char *src) { int i = 0; for (i = 0; src[i] != '\0'; i++) { dst[i] = src[i]; } dst[i] = '\0'; return dst; }

36 Example: strcpy using pointers char *strcpy (char *dst, const char *src) { char *retval = dst; while (*dst++ = *src++) ; return retval; }

37 Pointer Arithmetic  Cryptic (especially using together with ++ and --).  Error-prone.  Avoid using it.

38 Dynamic Memory Allocation  The proper use of pointer is for dynamic memory allocation.  Data structures of variable sizes can be constructed.

39 Sizes of data structures  Many data structures require known sizes during their creations.  Examples: arrays int a[5]; double d[MAX]; Student s[20];

40 Dynamic Sizes  However, many applications require data structures of dynamic sizes.  Examples: Tasks in an operating system Number of bidders in an auction People supporting Obama in Clear Lake

41 Memory Allocation  The new and new [] operators allocate the necessary memory and return the address.

42 Example p = new int; *p = 8; cout << "p = " << p << endl; cout << "*p = " << *p << endl; p = new int; // memory leakage. *p = 20; cout << "p = " << p << endl; cout << "*p = " << *p << endl; Output: p = 003354D8 *p = 8 p = 00335580 *p = 20

43 Example 2: Where is the error? int main(){ int* p, q; p = new int; *p = 8; q = p; cout << "p = " << p << endl; cout << "q = " << q << endl; p = new int; *p = 20; cout << "p = " << p << endl; cout << "q = " << q << endl; cout << "*p = " << *p << endl; cout << "*q= " << *q << endl; }

44 Example 2 int main(){ int *p, *q; p = new int; *p = 8; q = p; cout << "p = " << p << endl; cout << "q = " << q << endl; p = new int; *p = 20; cout << "p = " << p << endl; cout << "q = " << q << endl; cout << "*p = " << *p << endl; cout << "*q= " << *q << endl; }

45 Output of Example 2 p = 003354E0 q = 003354E0 p = 00335588 q = 003354E0 *p = 20 *q= 8

46 Memory Allocation  The memory structure for allocation through new operator is usually called heap.  The C++ Runtime may not have enough memory. Example: p = new int[1000000000]; MSVS: total size of array must not exceed 0x7fffffff bytes

47 Handling insufficient error int * p = new int [n]; // if it fails an exception bad_alloc is thrown. p = new (nothrow) int [5]; if (p == NULL) { // error allocating memory. };

48 Memory De-allocation  delete and delete [] are used to de- allocate memory for a single element and an array of elements respectively.  new and delete replaces malloc and free in C.  Example: int * p; … delete p;

49 Memory Corruption  Unintended pointer operations may cause memory corruption.

50 Example char *s1; delete s1; cause warning (“uninitialized local variable 's1' used”) and runtime exception.

51 Example char *s2 = new char[5]; delete s2; cause runtime exception.

52 Example char *s3; s3[2] = 10; cause runtime exception.

53 Example char *s4 = new char[10]; s4[10] = 'c'; cout << "s4[10] = " << s4[10] << endl; Output: s4[10] = c No error! But memory is corrupted!

54 Example char *t1 = new char('a'); char *t2 = t1; cout << "*t2 = " << *t2 << endl; delete t1; cout << "*t2 = " << *t2 << endl; Output: (no error!) *t2 = a *t2 = ▌  No other pointer referring to memory before de- allocation.

55 Memory Leakage  If the programmer forgets to de- allocate memory allocated by the new operator, memory leakage occurs.  Memory leakage is a notorious problem in C/C++. E.g. Web browsers.

56 Example char *s = new char; *s = 'c'; cout << "s[0] = " << s[0] << endl; s = new char('d'); cout << "*s = " << *s << endl; *s = 'e'; cout << "*s = " << *s << endl; Output: (with leakage) s[0] = c *s = d *s = e

57 Delete Before Re-Allocation char *s = new char; *s = 'c'; cout << "s[0] = " << s[0] << endl; delete s; s = new char('d'); cout << "*s = " << *s << endl; *s = 'e'; cout << "*s = " << *s << endl;

58 Example: Leakage int *i = new int(10); int *j = new int(15); i = j; cout << "*i = " << *i << endl; *j = 20; cout << "*i = " << *i << endl; Output: *i = 15 *i = 20

59 Example: What is the problem? char *s1 = new char[15]; char *s2 = new char[15]; strcpy(s1, "clinton"); s2 = s1; strcpy(s2, s1); delete [] s1;

60 Example: No memory corruption char *s1 = new char[15]; char *s2 = new char[15]; strcpy(s1, "clinton"); s2 = s1; strcpy(s2, s1); delete [] s1; delete [] s2;

61 The Culprit s2 = s1; strcpy(s2, s1);  The two statements have the same effect.  char * is unique as an indirection is automatically done.

62 C/C++ Dynamic Memory Allocation  Allow custom designed memory management.  Possibly more effective!  Error-prone.  Programming intensive

63 Java’s Approach  Java has no pointer.  Thus, there is no pointer arithmetic.  Java does have reference.  Programmers usually do not handle memory management.  “delete” is not a keyword in Java.

64 Automatic Garbage Collection  Java performs automatic garbage collection. Greatly simplify programmer’s work. Much less error-prone. Programmers lose control of memory management. Performance may be an issue, especially for real-time applications.

65 Java Reference  Java’s variable to objects are reference to the objects. Student s = new Student(“Yue”);  A Student object (Yue) is created.  s refers to the object.

66 C++ Objects and Pointers  Pointers to objects are similar to other pointers.

67 Example: C++ Rect r1 (2,3); Rect r2 (10,20); cout << "r1 area: " << r1.area() << endl; cout << "r2 area: " << r2.area() << endl; r1 = r2; cout << "r1 area: " << r1.area() << endl; r2.setWidth(7); cout << "r1 area: " << r1.area() << endl; cout << "r2 area: " << r2.area() << endl; Output: r1 area: 6 r2 area: 200 r1 area: 200 r2 area: 140

68 Example: Comparing to Java Rect r1 = new Rect(2,3); Rect r1 = new Rect(10,20); r1 = r2; r2.setWidth(7);

69 Similar Effect in C++ Rect *pr1 = & Rect(2,3); Rect *pr2 = & Rect(10,20); cout area() << endl; cout << "*pr2 area: " << (*pr2).area() << endl; pr1 = pr2; cout << "*pr1 area: " << (*pr1).area() << endl; pr2.setWidth(7); cout << "*pr1 area: " << (*pr1).area() << endl; cout << "*pr2 area: " << (*pr2).area() << endl;

70 Questions and Comments?


Download ppt "Pointers by Dr. Bun Yue Professor of Computer Science 2013 CSCI 3333 Data Structures."

Similar presentations


Ads by Google