Lec8. Pointers, Dynamic Arrays, Copy Constructor
Lec8. Pointers, Dynamic Arrays, Copy Constructor
Pointers and
Dynamic Arrays
10-2
Pointing
int *p, v; 42
p = &v;
– Sets pointer variable p to "point to" int variable v
– p and v refer to same variable
• Operator & determines "address of" variable
• Read like: "p equals address of v“ or "p points to v “
• Two ways to refer to v now: v = 0;
p = &v;
– Variable v itself: cout << v; *p = 42;
cout << v << endl;
– Via pointer p: cout *p; cout << *p << endl;
10-3
Pointer Assignments
• Pointer variables can be "assigned":
– Assigns one pointer to another
int *p1, *p2;
– "Make p1 point to where p2 points" p1 = p2;
10-4
Memory Management
• Stack: special memory region
– stores temporary variables created by each function,
– Automatically managed by the OS/CPU.
– Every time a function declares a new variable, it is
"pushed" onto the stack.
– When a function exits, all variables that it pushed
onto the stack, are deleted.
10-6
Basic Pointer Manipulations Example:
#include <iostream>
using namespace std;
int main( ){
int *p1, *p2;
p1 = new int;
*p1 = 42;
p2 = p1;
cout << "*p1 == " << *p1 << endl;
cout << "*p2 == " << *p2 << endl;
*p2 = 53;
cout << "*p1 == " << *p1 << endl;
cout << "*p2 == " << *p2 << endl;
p1 = new int;
*p1 = 88;
cout << "*p1 == " << *p1 << endl;
cout << "*p2 == " << *p2 << endl;
cout << "Hope you got the point of this example!\n";
return 0;
} *p1 == 42
*p2 == 42
*p1 == 53
*p2 == 53
*p1 == 88
*p2 == 53
10-7
Hope you got the point of this example!
Checking new Success
• Test if null returned by call to new:
– If new succeeded, program continues
int *p;
p = new int;
if (p == NULL) // NULL represents empty pointer
{
cout << "Error: Insufficient memory.\n";
exit(1);
}
10-8
delete Operator
• De-allocate dynamic memory using delete operator:
– When no longer needed int *p;
p = new int(5);
– Returns memory to freestore
… //Some processing…
– Literally "destroys" memory
delete p;
p = NULL;
• delete p; // Destroys dynamic memory
– But p still points there! : "dangling pointer"
– If p is then dereferenced ( *p ) is unpredicatable!
– Avoid dangling pointers by assign pointer to NULL after delete
10-14
#include <iostream>
using namespace std;
typedef int* IntPtr;
Dynamic
void fillArray( int a[], int size);
int search( int a[], int size, int target);
Arrays
int main( ) {
cout << "This program searches a list of numbers.\n";
int arraySize;
cout << "How many numbers will be on the list? ";
cin >> arraySize;
IntPtr a; This program searches a list of numbers.
a = new int[arraySize]; How many numbers will be on the list? 5
fillArray(a, arraySize); Enter 5 integers.
int target; 12345
cout << "Enter a value to search for: "; Enter a value to search for: 3
cin >> target;
3 is element 2 in the array.
int location = search(a, arraySize, target);
if (location == -1) cout << target << " is not in the array.\n";
else cout << target << " is element " << location << " in the array.
n";
delete [] a;
return 0;
}
void fillArray( int a[], int size){
cout << "Enter " << size << " integers.\n";
for ( int index = 0; index < size; index++) cin >> a[index];
}
int search( int a[ ], int size, int target) {
int index = 0;
while ((a[index] != target) && (index < size)) index++;
if (index == size) index = -1; //if target is not in a. 10-15
return index;
Pointer Arithmetic
• Can perform arithmetic on pointers: "Address" arithmetic
typedef double* DoublePtr;
– d contains address of d[0] DoublePtr d;
– d + 1 evaluates to address of d[1] d = new double[10];
– d + 2 evaluates to address of d[2]
• Equates to "address" at these locations
PFArrayD::~PFArrayD( ){
delete [] a;
}
10-21
#include <iostream>
using namespace std;
#include "parray.h" parrayDemo.cpp
void testPFArrayD( );
//Conducts one test of the class PFArrayD.
int main( )
{
cout << "This program tests the class PFArrayD.\n";
char ans;
do
{
testPFArrayD( );
cout << "Test again? (y/n) ";
cin >> ans;
} while ((ans == 'y') || (ans == 'Y'));
return 0;
}
MyClass::~MyClass() PFArrayD::~PFArrayD( ){
{ delete [] a;
//Perform delete clean-up duties }
}
10-25
Copy Constructors
• constructor that has one parameter of the same type as the class
– parameter must be a call-by-reference parameter normally preceded const
PFArrayD( const PFArrayD& obj);
PFArrayD b(20);
for ( int i = 0; i < 20; i++)
b.addElement(i);
PFArrayD temp(b); //Initialized by the copy constructor
PFArrayD::PFArrayD( int size) :capacity(size), used(0){
a = new double[capacity];
}
10-26
Copy Constructors
• Automatically called when:
1. Class object declared and initialized to other object
2. When function returns class type object
3. When argument of class type is "plugged in“ as actual argument to call-by-
value parameter
• Requires "temporary copy" of object
– Copy constructor creates it
• Default copy constructor
– Like default "=", performs member-wise copy
• Pointers write own copy constructor!
10-27
Shallow and Deep Copies
• Shallow copy
– Assignment copies only member variable contents over
– Default assignment and copy constructors
– Works fine if there are no pointers or dynamically allocated data
involved
• Deep copy
– Pointers, dynamic memory involved
– Must dereference pointer variables to "get to" data for copying
– Write your own assignment overload and copy constructor in this
case!
10-28
For you to think of them
int i = 3;
int* p = i; // invalid conversion from int to int*
int i = 3;
int* p = &i;
int i = 3;
int* p = &i;
int* q = p;
int i = 3;
int* p = &i;
int** q = &p;
For you to think of them
int& q = *p;
q = 4;
int* r = &q;
*r = 5;
int*& s = p;
*s = 6;