Presentation is loading. Please wait.

Presentation is loading. Please wait.

Pointers, Arrays, And Dynamic Memory Allocation by Bindra Shrestha CSCI 3333 Data Structures.

Similar presentations


Presentation on theme: "Pointers, Arrays, And Dynamic Memory Allocation by Bindra Shrestha CSCI 3333 Data Structures."— Presentation transcript:

1 Pointers, Arrays, And Dynamic Memory Allocation by Bindra Shrestha CSCI 3333 Data Structures

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

3 Memory Address & Pointers Each byte in the primary memory has an address. A pointer is a variable that stores a memory address of another variable. The address (reference) operator & is used to return the address of a variable. char ch = ‘q’; char* p = & ch;//&returns & of ch cout << *p; //outputs q by dereferencing

4 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 int *x, y, z; //int *x, int y, int z

5 Pointer Type Checking A pointer variable of a particular type cannot store address of an incompatible type. 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”

6 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; }

7 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

8 Pointer Type Checking A pointer variable of a particular type cannot store address of an incompatible type. 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”

9 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.

10 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; }

11 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

12 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;

13 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

14 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; }

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

16 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;

17 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;

18 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”

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

20 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). Pointers and arrays point to elements of the same type.

21 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 = 0012FF66 a+6 = 0012FF74

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

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

24 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

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

26 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

27 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.

28 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

29 Why Pointer Arithmetic Efficiency!

30 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; }

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

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

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

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

35 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 first women vice president in Clear Lake

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

37 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

38 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; }

39 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; }

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

41 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

42 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. };

43 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;

44 Memory Corruption Unintended pointer operations may cause memory corruption.

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

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

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

48 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!

49 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.

50 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++.

51 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

52 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;

53 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

54 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;

55 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;

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

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

58 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.

59 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.

60 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.

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

62 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

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

64 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;

65 Questions and Comments?


Download ppt "Pointers, Arrays, And Dynamic Memory Allocation by Bindra Shrestha CSCI 3333 Data Structures."

Similar presentations


Ads by Google