Download presentation
Presentation is loading. Please wait.
Published byOswin Shepherd Modified over 8 years ago
1
Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory
2
L-values R-values pointer types null address dereference operator * indirect members selector -> address operator & pointer assignment indirect assignment pointers as parameters pointers to pointers constant pointers pointers to constants arrays and pointers pointers to function dynamic objects free store operators new and delete exception handling dangling pointers memory leak destructors copy constructor member assignment this pointer qualifier const Key Concepts:
3
Usefulness Necessary for dynamic objects Objects whose memory is acquired during program execution as the result of a specific program request Dynamic objects can survive the execution of the function in which they are acquired Dynamic objects enable variable-sized lists, for example, the vector class The acquired memories of most programs can not be determined in compiling phase of program, but at run time
4
Memory address Memory and its address
5
Main board Graphics adapterSound blaster Hard disk driver Main memory CPU
6
Memory address Memory and its address System Bus CPUMemory Output device Input device
7
Memory address Memory and its address System bus transfers the data information, address information and control information Data bus transfers the data information Address bus transfers the address information Control bus transfers the control information 32 bits address bus has an ability of addressing memory space of 4GB From 0x00000000 to 0xFFFFFFFF
8
Memory address Memory and its address Main memory 0x00000001 0x00000000 0x00000002 0x00000003 0x7FFFFFFF 0xFFFFFFFD 0xFFFFFFFE 0xFFFFFFFF NULL address..................
9
L-value and R-value L-value expressions Represent objects that can be evaluated and modified R-value expressions Represent objects that can only be evaluated Consider int a; vector b(3); int c[3]; a = 1; // a: lvalue c[0] = 2*a + b[0]; // c[0], a, b[0]: lvalues Observation Not all lvalues are the names of objects
10
Pointer basics Pointer Object whose value represents the location of another object In C++ there are pointer types for each type of object Pointers to int objects Pointers to char objects Pointers to RectangleShape objects Even pointers to pointers Pointers to pointers to int objects Normally a pointer is an unsigned integer, its size is variable with the operation system and compiler A 32 bits pointer occupies itself 4 bytes of memory A 16 bits pointer occupies itself 2 bytes of memory
11
Examples of initialized pointers int i = 1; char c = 'y'; int *ptr = &i; // ptr is a pointer to int i char *t = &c; // t is a pointer to a char c Examples of uninitialized pointers int *iPtr; // iPtr is a pointer to an int char *s ; // s is a pointer to a char Rational *rPtr; // rPtr is a pointer to a // Rational Syntax TypeName * PointerName = &ObjectName Indicates pointer object Indicates to take the address of the object
12
Indirection Operator * An asterisk has two uses with regard to pointers In a definition, it indicates that the object is a pointer char *s; // s is of type pointer to char In expressions, when applied to a pointer it evaluates to the object to which the pointer points int i = 1; int *ptr = &i; // ptr points to i *ptr = 2; cout << i << endl; // display a 2
13
Address Operator & In a definition, & is used to define a reference to an object In expressions, when applied to a object as unary operator, & evaluates the address of the object int i = 1; int j = 2; int *ptr; ptr = &i; // ptr points to location of i *ptr = 3; // contents of i are updated ptr = &j; // ptr points to location of j *ptr = 4; // contents of j are updated cout << i << " " << j << endl;
14
Memory Depiction 0xF001 0xF002 0xF003 0xF004 0xF000 0xF005 0xF006 0xF008 0xF009 0xF00A 0xF00B 0xF007 0xF00C 0xF00D c char c = 'y'; int *ptr = &i; ptr char *t = &c; t ’y’ *ptr = 2; *t = ’W’; ’W’ ptr = (int*)&c; t = (char*)&i; 0xF004 0xF000 0xF004 i int i = 1; 12
15
Null Address 0 is a pointer constant that represents the empty or null address Its value indicates that pointer is not pointing to a valid object Cannot dereference a pointer whose value is null int *ptr = 0; cout << *ptr << endl; // invalid, ptr // does not point to // a valid int
16
Big advise Pointers are error prone and should be carefully manipulated. We always prefer to use reference object instead of pointer object when ever possible Pointer should be always initialized at definition. If there is not a object to point to, initialize it with null pointer (set its value to 0) First check the validity of a pointer before using it if( ptr != 0 ) cout << *ptr << endl;
17
Consider Rational r(4,3); Rational *rPtr = &r; To select a member of r using rPtr and member selection, operator precedence requires (*rPtr).Insert(cout); This syntax is clumsy, so C++ provides the indirect member selector operator -> rPtr->Insert(cout); Member Indirection
18
Pointers as parameters void IndirectSwap(char *Ptr1, char *Ptr2) { char c = *Ptr1; *Ptr1 = *Ptr2; *Ptr2 = c; } int main() { char a = 'y'; char b = 'n'; IndirectSwap(&a, &b); cout << a << b << endl; return 0; }
19
Pointers to pointers int i = 5; int *Ptr = &i; int **PtrPtr = 0; PtrPtr = &Ptr; PtrPtr Ptr i 5 100110021003100410111012101310141101110211031104 cout << Ptr << endl; cout << PtrPtr << endl; Cout << *Ptr << endl; cout << *PtrPtr << endl; cout << **PtrPtr << endl; // 1001 // 1011 // 5 // 1001 // 5
20
Constants and Pointers A constant pointer is a pointer such that we cannot change the location to which the pointer points char c = 'c'; const char d = 'd'; char * const ptr1 = &c; ptr1 = &d; // illegal *ptr1 = ’e’; // legal A pointer to a constant value is a pointer object such that the value at the location to which the pointer points is considered constant const char *ptr2 = &d; *ptr2 = 'e'; // illegal: cannot change d // through indirection with ptr2 Ptr2 = &c; // legal
21
Arrays and Pointers In C++ the name of an array is consider to be a constant pointer and points to first element of the array int A[5] = {10,20,30,40,50}; int B[10]={0}; Ptr1 1000 1004 1008 1012 1016 1020 1024 1028 1032 1036 1040 1044 1048 1052 1056 1060 A[0] A[1] A[2] A[3] A[4] B[0] B[1] B[2] B[3] B[4] B[5] B[6] B[7] B[8] B[9] Ptr2 Ptr3 Ptr4 10 20 30 40 50 0 0 0 0 0 0 0 0 0 0 int *Ptr1 = A; int *Ptr2 = B; int *Ptr3 = &B[0]; int *ptr4 = &B[5];
22
Arrays and Pointers Increment and decrement operator can be applied to any type of pointer object ++Ptr1; cout<< ptr1 << endl; cout<< *ptr1 << endl; --Ptr4; cout<< ptr4 << endl; cout<< *ptr4 << endl; Ptr1 1000 1004 1008 1012 1016 1020 1024 1028 1032 1036 1040 1044 1048 1052 1056 1060 A[0] A[1] A[2] A[3] A[4] B[0] B[1] B[2] B[3] B[4] B[5] B[6] B[7] B[8] B[9] Ptr4 10 20 30 40 50 0 0 0 0 0 0 0 0 0 0 10042010360
23
Arrays and Pointers Ptr1 1000 1004 1008 1012 1016 1020 1024 1028 1032 1036 1040 1044 1048 1052 1056 1060 A[0] A[1] A[2] A[3] A[4] B[0] B[1] B[2] B[3] B[4] B[5] B[6] B[7] B[8] B[9] 10 20 30 40 50 0 0 0 0 0 0 0 0 0 0 Ptr1 += 3; cout<< Ptr1 << endl; cout<< *Ptr1 << endl; Ptr4 -= 4; cout<< Ptr4 << endl; Ptr1 = Ptr4 + 3; cout<< Ptr4 << endl; Ptr4 += 9; int *Ptr = Ptr1 + Ptr2 // illegal Offset operation for pointer object Pointer object plus or minus a integer constant Ptr4 //be dangerous!!!
24
Arrays and Pointers Ptr1 1000 1004 1008 1012 1016 1020 1024 1028 1032 1036 1040 1044 1048 1052 1056 1060 A[0] A[1] A[2] A[3] A[4] B[0] B[1] B[2] B[3] B[4] B[5] B[6] B[7] B[8] B[9] 10 20 30 40 50 0 0 0 0 0 0 0 0 0 0 cout<< Ptr1 << endl; cout<< Ptr1[0] << endl; cout<< *Ptr1 << endl; cout<< Ptr1[3] << endl; cout<< *(Ptr1+3) << endl; Subscribing a pointer object [ ] operator for pointer
25
Pointers to function Usage: as function parameters Some member functions of SimpleWindow void SetTimerCallback(TimerTickCallbackFunction Callback); The name of a function is just a pointer to the function Definition of pointers to function ReturnType ( *FuncPtrName ) ( ParameterList ); int (*TimerTickCallbackFunction)(); int (*MouseClickCallback)(const Position &);
26
Dynamic objects whose memory is acquired at run time
27
Local objects and parameters Object memory is acquired automatically Object memory is returned automatically when object goes out of scope Dynamic objects 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 Deference with local object
28
Operation specifies The type and number of objects If there is sufficient memory to satisfy the request A pointer to sufficient memory is returned by the operation If there is insufficient memory to satisfy the request An exception is generated An exception is an error state/condition which if not handled (corrected) causes the program to terminate General New Operation Behavior Memory for dynamic objects Requested from the free store Free store is memory controlled by operating system
29
The Basic New Form Syntax Beware The newly acquired memory is uninitialized unless there is a default TypeName constructor Ptr = new TypeName ; Where Ptr is a pointer of type TypeName
30
Examples int *iptr = new int; Rational *rptr = new Rational; -- iptr 0/1 rptr Rational object with default initialization Uninitialized int object
31
Another Basic New Form Initialization The newly acquired memory is initialized using a TypeName constructor ParameterList provides the parameters to the constructor Syntax TypeName *Ptr = new TypeName(ParameterList); Where Ptr is a pointer of type TypeName
32
Examples int *iPtr = new int(10); Rational *rPtr = new Rational(1,2); rPtr 10 iPtr 1/2
33
The Primary New Form Syntax Where Ptr is a pointer of type SomeType SizeExpression is the number of contiguous objects of type TypeName to be constructed -- we are making a list Note The newly acquired list is initialized if there is a default TypeName constructor Because of flexible pointer syntax Ptr can be considered to be an array TypeName *Ptr = new TypeName[SizeExpression];
34
Examples int *A = new int [3]; Rational *R = new Rational[2]; A[1] = 5; Rational r(2/3); R[0] = r; — A 2/3 R 5 0/1 —
35
Right Array For The Job cout << "Enter list size: "; int n; cin >> n; int *A = new int[n]; GetList(A, n); SelectionSort(A, n); DisplayList(A, n); Note: Use of the container classes of the STL is preferred from a software engineering viewpoint. For example vector class
36
Delete Operators Forms of request // used if storage came from new delete P; // used if storage came from new[] delete [] P; Storage pointed to by P is returned to free store, and any program can reuse it P is now undefined
37
Cleaning Up int n; cout << "Enter list size: "; cin >> n; int *A = new int[n]; GetList(A, n); SelectionSort(A, n); DisplayList(A, n); delete [] A;
38
Dangling Pointer Pitfall int *A = new int[5]; for (int i = 0; i < 5; ++i) A[i] = i; int *B = A; A B 01234 A B 0 ? Beware this memory do not belong to the program any more delete [] A; A = 0; if(B != 0) cout << B[0] << endl; //???
39
Memory Leak Pitfall int *A = new int [5]; for (int i = 0; i < 5; ++i) A[i] = i; A 01234 A 01234 -- These memory cannot be accessed by any program A = new int [5];
40
A Simple Dynamic List Type A good example of the usage of dynamic objects What we want An integer list data type IntList with the basic features of the vector data type from the Standard Template Library Features and abilities True object Can be passed by value and reference Can be assigned and copied Inspect and mutate individual elements Inspect list size Resize list Insert and extract a list
41
Sample IntList Usage IntList A( 5, 1); IntList B(10, 2); IntList C( 5, 4); for (int i = 0, i < A.size(); ++i) { A[i] = C[i]; } cout << A << endl; // [ 4 4 4 4 4 ] A = B; A[1] = 5; cout << A << endl; // [ 2 5 2 2 2 2 2 2 2 2 ]
42
IntList Definition class IntList { public: // constructors IntList(int n = 10, int val = 0); IntList(const int A[], int n); IntList(const IntList &A); // destructor ~IntList(); // inspector for size of the list int size() const; // assignment operator IntList & operator=(const IntList &A);
43
IntList Definition (continued) public: // inspector for element of constant list const int& operator[](int i) const; // inspector/mutator for element of // nonconstant list int& operator[](int i); // resize list void resize(int n = 0, int val = 0); // convenience for adding new last element void push_back(int val); private: // data members int *Values; // pointer to elements int NumberValues; // size of list };
44
IntList Definition (continued) // IntList auxiliary operators -- nonmembers ostream& operator<<(ostream &sout, const IntList &A); istream& operator>>(istream &sin, IntList &A);
45
Default Constructor IntList::IntList(int n, int val) { assert(n > 0); NumberValues = n; Values = new int [n]; assert(Values); for (int i = 0; i < n; ++i) { Values[i] = val; }
46
Gang of Three Rule If a class has a data member that points to dynamic memory then that class normally needs a class-defined Copy constructor Constructor that builds an object out of an object of the same type Member assignment operator Resets an object using another object of the same type as a basis Destructor Anti-constructor that typically uses delete the operator on the data members that point to dynamic memory
47
Why A Tailored Copy Constructor Suppose we use the default copy constructor IntList A(3, 1); IntList B(A); B 3 111 A 3 2 And then A[2] = 2; Then B[2] is changed! Not what a client would expect Implication Must use tailored copy constructor
48
Why A Tailored Copy Constructor An other case, suppose we use the default copy constructor IntList A(3, 1); { IntList B(A); B[1] = 5;... } A[2] = 2; //what happened ??? Implication Must use tailored copy constructor B 3 11 A 3 1 5 ???
49
Tailored Copy Constructor IntList::IntList(const IntList &A) { NumberValues = A.size(); Values = new int [size()]; assert(Values); for (int i = 0; i < size(); ++i) Values[i] = A[i]; } What kind of subscripting is being performed? A 3 111 1 B 3 111 1
50
Gang Of Three What happens when an IntList goes out of scope? If there is nothing planned, then we would have a memory leak Need to have the dynamic memory automatically deleted Define a destructor A class object going out of scope automatically has its destructor invoked IntList::~IntList() { delete [] Values; }
51
This Pointer Consider this Inside a member function or member operator this is a pointer to the invoking object IntList::size() { return NumberValues; } or equivalently IntList::size() { return this->NumberValues; }
52
First Assignment Attempt Algorithm Return existing dynamic memory to free store Acquire sufficient new dynamic memory Copy the size and the elements of the source object to the target element
53
Initial Implementation (Wrong) IntList& operator=(const IntList &A) { NumberValues = A.size(); delete [] Values; Values = new int [NumberValues ]; assert(Values); for (int i = 0; i < A.size(); ++i) Values[i] = A[i]; return A; } Consider what happens with the code segment IntList C(5,1); C = C;
54
Member Assignment Operator IntList& IntList::operator=(const IntList &A) { if (this != &A) { delete [] Values; NumberValues = A.size(); Values = new int [A.size()]; assert(Values); for (int i = 0; i < A.size(); ++i) { Values[i] = A[i]; } return *this; }
55
Accessing List Elements // Compute an rvalue (access constant element) const int& IntList::operator[](int i) const { assert((i >= 0) && (i < size())); return Values[i]; } // Compute an lvalue int& IntList::operator[](int i) { assert((i >= 0) && (i < size())); return Values[i]; }
56
Stream Operators Should they be members? class IntList { //... ostream& operator<<(ostream &sout); //... }; Answer is based on the form we want the operation to take IntList A(5,1); A << cout; // member form (unnatural) cout << A; // nonmember form (natural)
57
Beware of Friends If a class needs to Can provide complete access rights to a nonmember function, operator, or even another class Called a friend Declaration example class IntList { friend ostream& operator<< ( ostream &sout, const IntList &A); friend istream& operator>> ( ostream &sin, const IntList &A); //... };
58
Implementing Friend << ostream& operator<<(ostream &sout, const IntList &A) { sout << "[ "; for (int i = 0; i < A.NumberValues; ++i) { sout << A.Values[i] << " "; } sout << "]"; return sout; } Why client can directly access the private data member of A ? Is it a good program ???
59
Proper << Implementation ostream& operator<<(ostream &sout, const IntList &A) { sout << "[ "; for (int i = 0; i < A.size(); ++i) { sout << A[i] << " "; } sout << "]"; return sout; }
60
End of Chapter 11 Exercises 11.47, 11.49 and 11.50 as in one Exercises 11.55 Home works
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.