 Download Download Presentation Pointer: Dynamic Allocation

# Pointer: Dynamic Allocation

Download Presentation ## Pointer: Dynamic Allocation

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -
##### Presentation Transcript

1. Pointer: Dynamic Allocation This lecture prepared by the instructors at the University of Manitoba in Canada and has been modified by Dr. Ahmad Reza Hadaegh

2. Dynamic Allocation - Main memory can be thought of as a (very) large one-dimensional array of memory locations - Each location holds 1 byte and has its own address - Starts at 0 in increments of 1 - Usually in hexadecimal - 0000 - FFFF represents 64K of memory - 64 * 1024 = 65,536 memory locations 0000 0001 0002 0003 0004 0005 •• FFFF

3. Dynamic Allocation - When variables are declared they are allocated memory - An integer requires (say) 4 bytes and thus gets 4 consecutive locations in memory - Most machines would store an int in 4 bytes - The address of the integer is the first byte and is effectively stored via the variable name

4. Dynamic Allocation - An integer variable X would effectively “point” to the starting address of the 4 bytes required - X must be dereferenced in order to be used - Dereference means to interpret what exists at a particular memory location - Dereference is implicit here memory integer variable X

5. Dynamic Allocation - It is possible to explicitly declare a variable that contains the address of other variables - Creating variables that are pointers

6. typedef int* intptr; int main ( ) { intptr ptr1; Dynamic Allocation Must be a pointer to a valid C++ type (either built-in or user defined type) intptr is a pointer to an integer •••

7. Syntax notes: Dynamic Allocation is the same as ... int main ( ) { int* ptr1; int* ptr2; int* ptr3; int main ( ) { int *ptr1, *ptr2, *ptr3; ••• •••

8. Dynamic Allocation - A pointer in C++ must point to storage of a particular type ptr1 is a pointer to an integer - ptr1 is a 4 byte variable that is able to point to a 4 byte variable - The value of ptr1 is not initialized and is at this point garbage

9. Dynamic Allocation - To allocate storage for ptr1 to point to: typedef int* intptr; int main ( ) { intptr ptr1; ptr1 = new int; 4 bytes of storage allocated for ptr1 to point to •••

10. Dynamic Allocation - Unlike “normal” variables, pointers must be explicitly dereferenced *ptr1 = 200; Store 200 in the 4 bytes pointed to by ptr1

11. Dynamic Allocation - Other manipulation may take place i = *ptr1; Assign 200 to integer variable i

12. Dynamic Allocation Other manipulation may not sensibly take place i = ptr1; Assign the address that ptr1 points to to integer variable i?

13. Dynamic Allocation - What happens here? ptr1 only exists once -- as such, each “new” points ptr1 to newly allocated 2 byte area typedef int* intptr; void main () { intptr ptr1; int i; for (i=1;i<=1000;i++) { ptr1 = new int; *ptr1 = 1234; } } The first 999 storage areas are reserved by the OS, but no longer accessible Memory leak! - Memory leaks are common problems in many applications

14. Dynamic Allocation - Storage that is allocated via “new” should be freed via “delete” during the execution of a program typedef int* intptr; void main () { intptr ptr1; int i; for (i=1;i<=1000;i++) { ptr1 = new int; *ptr1 = 1234; delete ptr1; } } Not really useful, but you get the point

15. Dynamic Allocation typedef int* intptr; void main () { intptr P, Q; P = new int; *P = 1 Q = new int; *Q = 2; cout << *P << ‘ ’ << *Q << endl; *P = *Q + 3; cout << *P << ‘ ’ << *Q << endl; P = Q; cout << *P << ‘ ’ << *Q << endl; } ? P ? Q •••

16. Dynamic Allocation typedef int* intptr; void main () { intptr P, Q; P = new int; *P = 1 Q = new int; *Q = 2; cout << *P << ‘ ’ << *Q << endl; *P = *Q + 3; cout << *P << ‘ ’ << *Q << endl; P = Q; cout << *P << ‘ ’ << *Q << endl; } ? P ? Q •••

17. Dynamic Allocation typedef int* intptr; void main () { intptr P, Q; P = new int; *P = 1 Q = new int; *Q = 2; cout << *P << ‘ ’ << *Q << endl; *P = *Q + 3; cout << *P << ‘ ’ << *Q << endl; P = Q; cout << *P << ‘ ’ << *Q << endl; } 1 P ? Q •••

18. Dynamic Allocation typedef int* intptr; void main () { intptr P, Q; P = new int; *P = 1 Q = new int; *Q = 2; cout << *P << ‘ ’ << *Q << endl; *P = *Q + 3; cout << *P << ‘ ’ << *Q << endl; P = Q; cout << *P << ‘ ’ << *Q << endl; } 1 P ? Q •••

19. Dynamic Allocation typedef int* intptr; void main () { intptr P, Q; P = new int; *P = 1 Q = new int; *Q = 2; cout << *P << ‘ ’ << *Q << endl; *P = *Q + 3; cout << *P << ‘ ’ << *Q << endl; P = Q; cout << *P << ‘ ’ << *Q << endl; } 1 P 2 Q •••

20. Dynamic Allocation typedef int* intptr; void main () { intptr P, Q; P = new int; *P = 1 Q = new int; *Q = 2; cout << *P << ‘ ’ << *Q << endl; *P = *Q + 3; cout << *P << ‘ ’ << *Q << endl; P = Q; cout << *P << ‘ ’ << *Q << endl; } 1 P 2 Q Output: 1 2 •••

21. Dynamic Allocation typedef int* intptr; void main () { intptr P, Q; P = new int; *P = 1 Q = new int; *Q = 2; cout << *P << ‘ ’ << *Q << endl; *P = *Q + 3; cout << *P << ‘ ’ << *Q << endl; P = Q; cout << *P << ‘ ’ << *Q << endl; } 5 P 2 Q •••

22. Dynamic Allocation typedef int* intptr; void main () { intptr P, Q; P = new int; *P = 1 Q = new int; *Q = 2; cout << *P << ‘ ’ << *Q << endl; *P = *Q + 3; cout << *P << ‘ ’ << *Q << endl; P = Q; cout << *P << ‘ ’ << *Q << endl; } 5 P 2 Q Output: 5 2 •••

23. Dynamic Allocation typedef int* intptr; void main () { intptr P, Q; P = new int; *P = 1 Q = new int; *Q = 2; cout << *P << ‘ ’ << *Q << endl; *P = *Q + 3; cout << *P << ‘ ’ << *Q << endl; P = Q; cout << *P << ‘ ’ << *Q << endl; } Memory leak! 5 P 2 Q •••

24. Dynamic Allocation typedef int* intptr; void main () { intptr P, Q; P = new int; *P = 1 Q = new int; *Q = 2; cout << *P << ‘ ’ << *Q << endl; *P = *Q + 3; cout << *P << ‘ ’ << *Q << endl; P = Q; cout << *P << ‘ ’ << *Q << endl; } Memory leak! 5 P 2 Q Output: 2 2 •••

25. Dynamic Allocation Memory leak! ••• *P = 7; cout << *P << ‘ ’ << *Q << endl; P = new int; delete P; P = NULL; Q = NULL; } 5 P 7 Q

26. Dynamic Allocation Memory leak! ••• *P = 7; cout << *P << ‘ ’ << *Q <<endl P = new int; delete P; P = NULL; Q = NULL; } 5 P 7 Q Output: 7 7

27. Dynamic Allocation Memory leak! ••• *P = 7; cout << *P << ‘ ’ << *Q << endl; P = new int; delete P; P = NULL; Q = NULL; } 5 P 7 Q ?

28. Dynamic Allocation Memory leak! ••• *P = 7; cout << *P << ‘ ’ << *Q << endl; P = new int; delete P; P = NULL; Q = NULL; } ? 5 P 7 Q

29. Dynamic Allocation Memory leak! ••• *P = 7; cout << *P << ‘ ’ << *Q << endl; P = new int; delete P; P = NULL; Q = NULL; } 5 P 7 Q

30. Dynamic Allocation Memory leaks! ••• *P = 7; cout << *P << ‘ ’ << *Q << endl; P = new int; delete P; P = NULL; Q = NULL; } 5 P 7 Q

31. NULL - Is a built-in constant that sets a pointer variable to something that can not be dereferenced - Also makes it clear that a pointer variable is in fact not pointing to anything - A garbage pointer may be non NULL and thus look like it’s pointing to something if (some_pointer = = NULL) cout << “pointer points to nothing” << endl; Dynamic Allocation

32. - Pointer variables can be initialized to NULL intptr a=NULL, b=NULL, c=NULL; - Probably a good habit to set pointer variables to NULL after deleting them Dynamic Allocation

33. Dynamic Allocation #include <iostream> using namespace std; typedef int* intptr; void main () { intptr ptr1; ptr1 = new int; *ptr1 = 12345; delete ptr1; cout << *ptr1 << endl; } Output?

34. Dynamic Allocation #include <iostream> using namespace std; typedef int* intptr; void main () { intptr ptr1; ptr1 = new int; *ptr1 = 12345; delete ptr1; ptr1 = NULL; cout << *ptr1 << endl; } Output?

35. - Using NULL does not guarantee that that you protect yourself from doing something silly as in: Dynamic Allocation

36. Dynamic Allocation #include <iostream> using namespace std; typedef int* intptr; void main () { intptr ptr1; ptr1 = new int; *ptr1 = 12345; delete ptr1; ptr1 = NULL; ptr1 = new int; cout << *ptr1 << endl; } Output?

37. Dynamic Allocation #include <iostream> using namespace std; typedef int* intptr; void main () { intptr ptr1, ptr2; ptr1 = new int; *ptr1 = 12345; delete ptr1; ptr1 = NULL; ptr2 = new int; ptr1 = new int; cout << *ptr1 << endl; } Output?

38. Dynamic Allocation - When dealing with pointers, you are responsible for ensuring they do not dangle Note: - Dynamic allocation is one of the most important topic of this course. So you need understand it very well.

40. Link List: Linked structures - Linked lists often provide an elegant alternative to structures such as arrays - A linked list is readily created in most procedural languages Linked lists are often represented in the following manner:

41. Linked Lists Pointer to next node top Data 27 -38 4 36 Last node’s pointer is NULL node

42. Linked List - The simplest linked structure - Sometimes called a linear linked list - The result of having an initial pointer to a node - And dynamically created nodes that point to other nodes - A dynamic incarnation of a simple array - Both have their advantages

43. Linked Lists - Big advantage over array in that linked list is dynamically created - Use only as many nodes as required for data - List grows and shrinks accordingly - Linked lists are made up of a pointer (“top” in this case) that points to the first of a collection of homogeneous nodes - Unlike the nodes, top contains no data top is not dynamically created while the rest of the linked structure is

44. Declaration for linked list class node; typedef node* nodeptr; class node { public: int number; nodeptr next; }; //-------------------------------- int main ( ) { nodeptr top; …. } Only variable declared

45. Linked Lists - All that exists at this time is an uninitialized pointer to a node - No nodes have been allocated yet - To make it clear the linked list is empty top = NULL; ••• NULL is a special C++ constant •••

46. Dereferencing: Allocating a node - The Code: top = new node; - Allocates space for a new node and place its starting memory address in top

47. Dereferencing - Given that a node exists and given that a pointer exists that contains the node’s address, the contents of the node may be modified - Again, using a pointer to reference storage is called dereferencing top -> number = 123; top -> next = NULL; Note the arrow notation that allows access to a field within a node

48. - Now have: 123 Dereferencing Remember that top is a declared variable -- a pointer to a node top This node is not a variable -- it is dynamically allocated via the new statement

49. top = new node; // again! New (again) top now points to a new node top top 123 123 Old node still exists, but can no longer be accessed -- memory leak!

50. Delete - Linked lists are dynamic which means they can grow and shrink appropriately - Grow with new - Shrink with delete