270 likes | 290 Views
Understand the concepts of dynamically allocated memory and pointer variables in C++. Learn about the heap and how to allocate and deallocate memory using pointers. Explore the use of pointers to dynamically allocate arrays.
E N D
Dynamically Allocated Memory pointer variables and the heap
. pointer what is pointed to a value of some type Pointer Variables • a pointer is a variable which holds the address of something else • called indirect addressing
“Do not mistake the pointing finger for the moon” a Zen saying
Some Uses of Pointer Variables • reference parameters in C++ and class instances in Java • the pointer is "hidden" • dynamically (run-time) allocated arrays • linked data structures • linked lists
"lifetime" of a variable • is a run-time concept • period of time during which a variable has memory space associated with it • begins when space is allocated • ends when space is de-allocated • three categories of "lifetime" • static - start to end of program execution • automatic (stack) - start to end of declaring function's execution • heap - starts with "new"; ends when: • Java: run-time system collects "garbage" • C++: "delete" statement executed
data memory model space for global variables static data run-time stack - activation records added and removed as program runs (expands and shrinks in an orderly LIFO manner) automatic data space for variables allocated at run-time using "new" (allocation and de-allocation requests occur in unpredictable order) heap data
Heap Variables • are accessed indirectly via a pointer variable • memory space is explicitly allocated at run-time (using new) • space is allocated from an area of run-time memory known as the heap • in C++ space must be explicitly returned (using delete)to avoid “memory leak” • C++ programmers are responsible for memory management
intPointer and timePointer are automatic variables timePointer intPointer ? ? Declaring Pointer Variables • syntax • <data type> * <pointer name>; • pointers are typed • some examples • int * intPointer; • Time * timePointer;
heap memory intPointer ? Assigning a value to a pointer variable • the value of a pointer variable is a memory address • assign address of an existing variable • int number; • intPointer = &number; • use "new" to allocate space in the heap • intPointer = new int; • address of heap memory space allocated becomes the value of the pointer variable
*intPointer intPointer Dereferencing • heap variables do not have a name of their own • are anonymous variables • *intPointer refers to the value pointed to by intPointer • intPointer is the finger; *intPointer is the moon • what happens? • intPointer = 36; • *intPointer = 36; • (*intPointer)++; • cout << *intPointer; • intPointer = null;
float * fPointer = new float; cin >> (*fPointer); ------ delete fPointer; Returning Heap Space • done by using the deletestatement • syntax • delete <pointer variable>; • example
Pointers - Summary • a pointer variable holds a memory address and can be used to create and access dynamic variables • dynamic (heap) variables are explicitly created at run-time (using new) • memory for dynamic variables is allocated in an area of memory called the heap • space used for dynamic variables needs to be freed (using delete) to avoid memory leaks
using pointers to dynamically allocate arrays Using C++ for an example
a C++ automatic array int entry [31]; value has to be known at compile time entry 34 45 15 ---------- 36 0 1 2 ----------- 30 NO HEAP MEMORY SPACE IN USE! entry[0] = = *entry
float * dynArray; // declare pointer only dynArray = new float [max]; // max is a variable // use of dynamic array the same as use of an automatic array delete [ ] dynArray; // free heap space C++ dynamic arrays • can use dynamic memory allocation to postpone decision about array capacity until run-time • array space will be on the heap • pointer to array's beginning is not on the heap
Stack class using a dynamic array • changes needed ? • data structure has changed so private data members will be different • constructor has to allocate the dynamic array • needs parameter to indicate capacity • once allocated capacity does not change • operations are the same • data member rather than constant for capacity • use of the heap requires added methods • destructor, copy constructor, operator=
data members needed? SE * myArray; int myTop; int myCapacity; Constructor must allocate the dynamic array needs a parameter to know how big an array to allocate someStack Stack::Stack (int size) { myCapacity = size; myArray = new SE[myCapacity]; assert (myArray != null); myTop = -1; } myArray myTop myCapacity Stack class
-1 someStack 5 myArray myTop myCapacity This space in on the heap This space in on the stack a Stack object void func ( ) { Stack someStack (5); ------ ------ } when func returns space for its activation record on the run-time stack is reclaimed
destructor • needed in order to prevent "memory leaks" • heap memory space which is no longer accessible but has not been returned (using delete) • destructor is a method that is called implicitly when the function in which an object was declared returns • compiler provides a "default destructor" • nothing more is needed unless the object makes use of heap memory space (allocates space using new) • to provide a destructor for Stack • in declaration: ~Stack( ); // class destructor • in implementation: Stack::~Stack( ) { delete [ ] myArray; }
copy constructor • needed in order to make a deep rather than a shallow copy of an object • when is a copy of an object made? • a value parameter requires a copy of the argument • void someFunc (Stack s) { ---- } • one object is created as a copy of an existing object • Stack a (10); • Stack b = a; // or Stack b (a); • a function/method returns an object • Stack func ( ) { Stack stackToBeReturned (8); ----- return stackToBeReturned;}
b myArray myTop myCapacity a 5 8 myArray myTop myCapacity 5 8 a shallow copy • compiler provides a default copy constructor • it makes a shallow copy when a copy is needed • nothing more is needed unless the object makes use of heap memory space (allocates space using new) Stack a (8); Stack b (a);
b myArray myTop myCapacity a 5 8 myArray myTop myCapacity 5 8 a deep copy • the copy must have its own heap memory space, the contents of which is the same as the object it is a copy of Stack a (8); Stack b (a);
myClass (const myClass & sourceObj); myClass::myClass (const myClass & sourceObj) { //copy all non-heap data members using = //allocate heap space required by the copy //copy data stored in sourceObj's heap //memory to new object's heap memory } a copy constructor makes a new deep copy of an existing object
copy constructor for Stack class declaration Stack (const Stack & sourceStack); Stack::Stack (const Stack & sourceStack) { myCapacity = sourceStack.myCapacity; myTop = sourceStack.myTop; myArray = new SE [myCapacity]; assert (myArray != null); for (int pos = 0; pos < myTop; pos++) { myArray[pos] = sourceStack.myArray[pos]; } } implementation
= replaces an object with a copy of an existing object • stackA = stackB; • compiler provided operator= replaces stackA with a shallow copy of stackB • heap space used by the "old" stack A becomes garbage • a class using heap memory must provide its own operator= • return heap memory currently used by stackA • replace stackA with a deep copy of stackB
void operator= (const myClass & SourceObj); void myClass::operator= (const myClass & SourceObj); { //deallocate heap space used by left hand operand //copy all non-heap data members using = //allocate new heap space for the left hand operand //copy data stored in sourceObj's heap memory //to left hand operand's heap memory } same job that is done by the copy constructor operator=
operator= for Stack class declaration void operator= (const Stack & sourceStack); void Stack::operator= (const Stack & sourceStack) { if (this != &sourceStack) // check for self copy { delete [ ] myArray; // deallocate previous array // same code as in the copy constructor // to make a deep copy of sourceStack } } implementation