Making the Array Dynamic
Objectives
We would like to :
- Review dynamic memory
Notes
- This is the first part of chapter 3.
- Remember
- Memory used in functions is allocated on the stack.
- This memory is "known" at compile time
- This memory is managed by the compiler.
- Pointer variables
-
datatype * var, * var;
- Initialize to
nullptr
- Always pointing to nullptr or valid memory.
- Dynamic memory is handeled by the user
- It is allocated off the heap.
- The user must allocate it.
- The user must deallocate it.
- Memory is allocated with
-
new datatype
for a single instance
-
new datatype[const int expression]
for an array.
- If the memory allocated is a class, the constructor is called.
- Memory is deallocated with
-
delete pointevar
-
delete[] pointervar
for arrays
- do not delete nullptr
- Always free allocated memory
- Unless we are exiting, always set pointer variables to nullptr after they have been deleted.
- The class destructor should be used to free dynamic memory in a class
-
~AClassT()
- A class with dynamic memory MUST have a class destructor.
- This is called when the class goes out of scope.
- No need to set any pointer variables to null, they go away.
- You can test for memory leaks, and other problems with
valgrind
- Accessing Dynamic Memory.
- We looked at this before.
- But *ptr will dereference the pointer, or follow the pointer to the memory.
- In a class or struct -> accesses the members.
- Copying structures/classes with dynamic memory
- Classes and structors are copied via the = (assignment) operator.
- They are also constructed with the copy constructor.
- The copy constructor is called
- When classes are passed by value
-
AClassT a;
AClassT b{a};
- And other places.
- If you do not provide one, the compiler will write one for you.
- The default assignment operator and copy constructor does a shallow copy
- This does a "copy" of all the data in the class.
- But only copies pointers, not the memory they point to.
- This leads to two instances of a class pointing to the same memory.
- And this is bad.
- And on destruction, one instance usually points to deallocated memory.
- This too is bad.
- In a deep copy the programmer makes copies of dynamic memory
- Allocate a new structure
- copy data from the original to the new.
- Make sure you copy all fields of the class
- Both dynamic and non-dynamic
- All classes with dynamic memory must implement a
- Copy constructor
- Overloaded assignment operator.
- A destructor.
- In modern c++ there are also move assignment operators and move copy constructors.
- We will postpone those for now.
- We will also postpoine a discussion of constructors, destructors, assignment operators and when the compiler will construct one for you.
- But in general if you have one of the three, it will not write any of the others for you.
- Including the default constructor.
- The function prototypes
-
AClassT( const AclassT & other)
- Must pass by reference, since this is how you pass by constant
- Should be constant reference
-
AClassT & operator = (const AClassT & other)
- Shold pass by const reference.
- Check to see
if (&other != this)
- for a = a, which is a legal statment.
- Return
*this
- Remember to test all of the big three
- Pass by value, construct a copy
- a = b, a = a.
- Please refer to AClassT.* in the code section.