Download presentation
Presentation is loading. Please wait.
1
Dynamic Structures & Arrays
2
What is a pointer variable?
A pointer variable is a variable whose value is the address of a location in memory. To declare a pointer variable, you must specify the type of value that the pointer will point to. For example, int* ptr; // ptr will hold the address of an int char* q; // q will hold the address of a char 2
3
Using a pointer variable
2000 12 x 3000 ptr int x; x = 12; int* ptr; ptr = &x; NOTE: Because ptr holds the address of x, we say that ptr “points to” x
4
Unary operator * is the deference (indirection) operator
2000 12 x 3000 ptr int x; x = 12; int* ptr; ptr = &x; std::cout << *ptr; NOTE: The value pointed to by ptr is denoted by *ptr
5
Using the dereference operator
int x; x = 12; int* ptr; ptr = &x; *ptr = 5; // changes the value // at adddress ptr to 5 2000 12 x 3000 ptr 5
6
Another Example char ch; ch = ‘A’; char* q; q = &ch; *q = ‘Z’;
char* p; p = q; // the right side has value 4000 // now p and q both point to ch 4000 A ch 5000 q Z 6000 4000 p
7
Pointer dereferencing and member selection
8
Dynamically Allocated Data
char* ptr; ptr = new char; *ptr = ‘B’; std::cout << *ptr; 2000 ptr New is an operator 8
9
Dynamically Allocated Data
char* ptr; ptr = new char; *ptr = ‘B’; std::cout << *ptr; NOTE: Dynamic data has no variable name 2000 ptr 9
10
Dynamically Allocated Data
char* ptr; ptr = new char; *ptr = ‘B’; std::cout << *ptr; 2000 ptr ‘B’ 10
11
Dynamically Allocated Data
char* ptr; ptr = new char; *ptr = ‘B’; std::cout << *ptr; delete ptr; 2000 ptr NOTE: Delete deallocates the memory pointed to by ptr. ? 11
12
what does new do? takes a pointer variable, allocates memory for it to point, and leaves the address of the assigned memory in the pointer variable. If there is no more memory, the pointer variable is set to NULL.
13
The NULL Pointer There is a pointer constant called NULL available in cstddef. NULL is not a memory address; it means that the pointer variable points to nothing. It is an error to dereference a pointer whose value is NULL. It is the programmer’s job to check for this. while (ptr != NULL) { // ok to use *ptr here }
14
What happens here? int* ptr = new int; 3 *ptr = 3; ptr
ptr = new int; // changes value of ptr *ptr = 4; 3 ptr 4 14
15
Memory Leak A memory leak occurs when dynamic memory (that was created using operator new) has been left without a pointer to it by the programmer, and so is inaccessible. int* ptr = new int; *ptr = 8; int* ptr2 = new int; *ptr2 = -5; 8 ptr -5 ptr2 How else can an object become inaccessible? 15
16
Causing a Memory Leak int* ptr = new int; *ptr = 8;
-5 ptr2 int* ptr = new int; *ptr = 8; int* ptr2 = new int; *ptr2 = -5; ptr = ptr2; // here the 8 becomes inaccessible 8 ptr -5 ptr2 16
17
Using operator delete The object or array currently pointed to by the pointer is deallocated, and the pointer is considered unassigned. The memory is returned to the free store. Square brackets are used with delete to deallocate a dynamically allocated array of classes. 17
18
A Dangling Pointer occurs when two pointers point to the same object and delete is applied to one of them. int* ptr = new int; *ptr = 8; int* ptr2 = new int; *ptr2 = -5; ptr = ptr2; 8 ptr -5 ptr2 18
19
Leaving a Dangling Pointer
8 ptr -5 ptr2 int* ptr = new int; *ptr = 8; int* ptr2 = new int; *ptr2 = -5; ptr = ptr2; delete ptr2; // ptr is left dangling ptr2 = NULL; 8 ptr NULL ptr2 19
20
Remember? A list is a homogeneous collection of elements, with a linear relationship between elements. Each list element (except the first) has a unique predecessor, and each element (except the last) has a unique successor.
21
ADT Unsorted List Operations
Transformers MakeEmpty PutItem DeleteItem Observers IsFull GetLength GetItem Iterators ResetList GetNextItem change state observe state process all
22
Do we have to keep a length field?
#include “ItemType.h” // unsorted.h class UnsortedType { public : // LINKED LIST IMPLEMENTATION // The public interface is the same private : // The private part is different NodeType<ItemType>* listData; int length; NodeType<ItemType>* currentPos; }; struct NodeType; struct NodeType { ItemType info; NodeType* next; } ; Do we have to keep a length field? Do we need an IsFull?
23
class UnsortedType<char>
Private data: length listData currentPos ? MakeEmpty ~UnsortedType ‘X’ ‘C’ ‘L’ GetItem PutItem DeleteItem . GetNextItem
24
// LINKED LIST IMPLEMENTATION ( unsorted.cpp ) #include “itemtype.h”
UnsortedType::UnsortedType ( ) // constructor // Pre: None. // Post: List is empty. { length = 0; listData = NULL; } int UnsortedType::GetLength( ) const // Post: Function value = number of items in the list. return length; 24
25
ItemType UnsortedType::GetItem( ItemType item, bool& found )
// Pre: Key member of item is initialized. // Post: If found, item’s key matches an element’s key in the list // a copy of that element is returned; otherwise, // original item is returned. { bool moreToSearch; NodeType<ItemType>* location; location = listData; found = false ; moreToSearch = ( location != NULL ); while ( moreToSearch && !found ) { if ( item == location->info ) // match here { found = true; item = location->info; } else // advance pointer { location = location->next; } } return item; 25
26
void UnsortedType::PutItem ( ItemType item )
// Pre: list is not full and item is not in list. // Post: item is in the list; length has been incremented. { NodeType<ItemType>* location; // obtain and fill a node location = new NodeType<ItemType>; location->info = item; location->next = listData; listData = location; length++; } 26
27
Inserting ‘B’ into an Unsorted List
Private data: length listData currentPos ? ‘X’ ‘C’ ‘L’
28
location = new NodeType;
item location ‘B’ Private data: length listData currentPos ? ‘X’ ‘C’ ‘L’
29
location->info = item ;
‘B’ ‘B’ Private data: length listData currentPos ? ‘X’ ‘C’ ‘L’
30
location->next = listData ;
item location ‘B’ ‘B’ Private data: length listData currentPos ? ‘X’ ‘C’ ‘L’
31
listData = location ; item ‘B’ location ‘B’ Private data: length 3
currentPos ? ‘X’ ‘C’ ‘L’
32
length++ ; item ‘B’ location ‘B’ Private data: length 4 listData
currentPos ? ‘X’ ‘C’ ‘L’
33
UML diagrams
34
Big-O Comparison of Unsorted List Operations
35
Arrays
36
One-Dimensional Array at the Logical Level
A one-dimensional array is a structured composite data type made up of a finite, fixed size (known at compile time) collection of homogeneous (all of the same data type) elements having relative positions and to which there is direct access (any element can be accessed immediately). Array operations (creation, storing a value, retrieving a value) are performed using a declaration and indexes.
37
Implementation Example
char name[10]; // assume element size is 1 byte This ACCESSING FUNCTION gives position of name[Index] Address(Index) = BaseAddress + Index * SizeOfElement Base Address name[0] name[1] name[2] name[3] name[4] name[9]
38
Another Example float values[5]; // assume element size is 4 bytes
This ACCESSING FUNCTION gives position of values[Index] Address(Index) = BaseAddress + Index * SizeOfElement float values[5]; // assume element size is 4 bytes Base Address values[0] values[1] values[2] values[3] values[4] Indexes
39
One-Dimensional Arrays in C++
The index must be of an integral type char, short, int, long, or enum The index range is always 0 through the array size minus 1 Arrays cannot be assigned one to another, and cannot be the return type of a function
40
Passing Arrays as Parameters
In C++, arrays are always passed by reference, and & is not used with the formal parameter type. Whenever an array is passed as a parameter, its base address is sent to the called function.
41
float SumValues (const float values[ ], numOfValues)
// Pre: values[ 0] through values[numOfValues-1] // have been assigned // Returns the sum of values[0] through // values[numOfValues-1] { float sum = 0; for ( int index = 0; index < numOfValues; index++ ) sum = values [index] + sum; } return sum;
42
Two-Dimensional Array at the Logical Level
A two-dimensional array is a structured composite data type made up of a finite, fixed size collection of homogeneous elements having relative positions and to which there is direct access. Array operations (creation, storing a value, retrieving a value) are performed using a declaration and a pair of indexes (called row and column) representing the component’s position in each dimension.
43
EXAMPLE -- To keep monthly high temperatures for
EXAMPLE -- To keep monthly high temperatures for states in a two-dimensional array. const int NUM_STATES = 50 ; const int NUM_MONTHS = 12 ; int stateHighs [ NUM_STATES ] [ NUM_MONTHS ] ; [ 0 ] [ 1 ] [ 2 ] . stateHighs [2] [7] [ 48 ] [ 49 ] [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] row 2, col 7 might be Arizona’s high for August
44
Finding the average high temperature for Arizona
float total = 0; int month; float average; for ( month = 0; month < NUM_MONTHS; month ++ ) total = total + stateHighs [ 2 ][ month ]; average = ( total / NUM_MONTHS);
45
const int NUM_STATES = 50 ; const int NUM_MONTHS = 12 ; int stateHighs [ NUM_STATES ] [ NUM_MONTHS ] ; STORAGE rows columns In memory, C++ stores arrays in row order. The first row is followed by the second row, etc. Base Address 8000 8024 8048 . . . 12 highs for state highs for state etc. Alabama Alaska first row second row
46
Implementation Level View
stateHighs[ 0 ] [ 0 ] stateHighs[ 0 ] [ 1 ] stateHighs[ 0 ] [ 2 ] stateHighs[ 0 ] [ 3 ] stateHighs[ 0 ] [ 4 ] stateHighs[ 0 ] [ 5 ] stateHighs[ 0 ] [ 6 ] stateHighs[ 0 ] [ 7 ] stateHighs[ 0 ] [ 8 ] stateHighs[ 0 ] [ 9 ] stateHighs[ 0 ] [10 ] stateHighs[ 0 ] [11 ] stateHighs[ 1 ] [ 0 ] stateHighs[ 1 ] [ 1 ] stateHighs[ 1 ] [ 2 ] stateHighs[ 1 ] [ 3 ] . Base Address 8000 To locate an element such as stateHighs [ 2 ] [ 7] the compiler needs to know that there are 12 columns in this two-dimensional array. At what address will stateHighs [ 2 ] [ 7 ] be found? Assume 2 bytes for type int.
47
Example of a 2-dimensional object
48
Two-Dimensional Array Parameters
Just as with a one-dimensional array, when a two- (or higher) dimensional array is passed as a parameter, the base address of the actual array is sent to the function. The size of all dimensions except the first must be included in the function heading and prototype. The sizes of those dimensions for the formal parameter must be exactly the same as in the actual array.
49
[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]
Use the two-dimensional stateHighs array to fill a one-dimensional stateAverages array const int NUM_STATES = 50 ; const int NUM_MONTHS = 12 ; int stateHighs [ NUM_STATES ] [ NUM_MONTHS ] ; float stateAverages [ NUM_STATES ] ; [ 0 ] ? [ 1 ] ? [ 2 ] . [ 48 ] [ 49 ] [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] Alaska Arizona
50
void findAverages ( const int stateHighs [NUM_STATES] [NUM_MONTHS], int stateAverages [NUM_STATES])
// Pre: stateHighs[ 0..NUM_STATES-1] [ 0..NUM_MONTHS-1] // assigned // Post: stateAverages[ 0..NUM_STATES-1 ] contains rounded // high temperature for each state { int state; int month; float total; for ( state = 0 ; state < NUM_STATES; state++ ) total = 0.0; for ( month = 0 ; month < NUM_MONTHS ; month++ ) total = stateHighs [ state ][ month ] + total; stateAverages [ state ] = total / NUM_MONTHS; }
51
Using typedef with arrays
helps eliminate the chances of size mismatches between formal and actual parameters. FOR EXAMPLE, typedef int StateHighsType [ NUM_STATES ][ NUM_MONTHS ]; typedef float StateAveragesType [ NUM_STATES ]; void findAverages( const StateHighsType stateHighs, StateAveragesType stateAverages ) { . }
52
Declaring Multidimensional Arrays
EXAMPLE USING TYPEDEF const int NUM_DEPTS = 5; // mens, womens, childrens, electronics, linens const int NUM_MONTHS = 12 ; const int NUM_STORES = 3 ; // White Marsh, Owings Mills, Towson typedef long MonthlySalesType [NUM_DEPTS] [NUM_MONTHS] [NUM_STORES]; MonthlySalesType monthlySales;
53
monthlySales[3][7][0] 3 STORES sheets 5 DEPTS rows
const int NUM_DEPTS = 5; // mens, womens, childrens, electronics,linens const int NUM_MONTHS = 12 ; const int NUM_STORES = 3 ; // White Marsh, Owings Mills, Towson typedef long MonthlySalesType [NUM_DEPTS] [NUM_MONTHS] [NUM_STORES] ; MonthlySalesType monthlySales; monthlySales[3][7][0] sales for electronics in August at White Marsh 3 STORES sheets 5 DEPTS rows 53 12 MONTHS columns
54
Overview
55
Overview The order of adding 1 to each element in a one dimensional array of N integers. A. O(1) B. O(logN) C. O(N) D. O(N logN) O(N*N) The order of adding 1 to each element in a square two dimensional array of integers where the number of rows is N. A. O(1) E. O(N*N)
56
Overview What is special about the last node in a dynamic linked list? A. Its component (data) member is empty. B. Its component (data) member contains the value 0. C. Its link member is empty. D. Its link member contains the value NULL. It has no link member. A fixed-sized structure; the mechanism for accessing the structure is built into C++. A variable-sized, user-defined structure; the mechanism for accessing the structure must be provided through functions. array list
57
Overview To prevent a compile-time error, how should the following code be changed? struct ListNode // Line 1 { // Line 2 int dataVal; // Line 3 NodeType* next; // Line 4 }; // Line 5 A. Insert the following before line 1: typedef ListNode* NodeType*; B. Insert the following before line 1: struct ListNode; C. Replace line 4 with the following: ListNode* next; D. Do either b or c above. E. Do any of a, b, or c above.
58
Overview What symbol does C++ use to terminate the internal representation of strings? A. 'n' B. '\n' C. '\0' D. '\#' E. C++ doesn't use a symbol to terminate a string. A generic data type is one in which the types of the items being manipulated are defined, but the operations are not. It is not possible to use a list without knowing how it is implemented. A constructor cannot be explicitly called by the client program. O(1) is called constant time. O(N) is called linear time. A destructor is a special operation that is implicitly called when a class object goes out of scope.
59
Overview Deleting from an unsorted list requires that the elements below the one being deleted be moved up one slot. The algorithms for finding an element in an unsorted list is O(n). The next item in a linked list always can be found by accessing the next physical location in memory. Given only the external pointer to a linked list, it is faster to insert a node at the front of the list than at the back. The external pointer is considered to be one of the nodes of a linked list If currPtr points to a node in a dynamic linked list, the operation currPtr++ advances to the next node in the list. Reading components into an initially empty list is faster if the list is represented directly as an array rather than a linked list. With a list ADT, insertions and deletions at the front of the list are faster with a linked list representation than with a direct array representation. With a list ADT, insertions and deletions at the back of the list are faster with a linked list representation than with a direct array representation.
60
Overview C++ ensures we do not write beyond allocated array slots.
The position of an element in a one dimensional array associated with Index is Address(Index) = Base + Index * SizeOfElement In a two dimensional array, component selection is as follows table[columnIndex][rowIndex]
61
Overview Members of a struct are public by default.
Members of a class are public by default. A struct differs from an array in that its elements need not occupy a consecutive block of memory cells. C++ provides a way to sequentially iterate through the fields in a struct.
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.