Chapter 18 - Memory Management


Chapter Goals



18.1 Categories of Memory

Memory is divided into four categories:
  1. Code - instructions for all global and member functions
  2. Static Data - global variables, and all local and member variables declared static
  3. Run-time Stack - automatics (local non-static)
  4. Free Store (Heap) - dynamically allocated (new)

18.1.1 Code Memory


18.1.2 Static Data Memory


18.1.3 The Run-time Stack


18.1.4 The Run-time Stack (example)

If function f has called g, which, in turn, called h, then the stack looks something like this:


Heap Memory

The heap, or free store:

18.2 Common Memory Errors


18.3 Constructors

(introduced in Chptr. 6)


18.3 (cont.) Constructors - String Example

E.g., String class, with underlying array on heap.

class String
{
public:
   String(); // Default constructor
   String(const char p[]); // Simple constructor
   String(const String& right); // Copy constructor
   ~String(); // Destructor
   String& operator=(const String& right); // Assignment operator
   String& operator+=(const String& right);
   int length() const;
   char& operator[](int index);
   char operator[](int index) const;
private:
   char* buffer;
   int len;
};

18.3.1 Constructors with Arguments


18.3.2 Default Constructors


18.3.2 Default Constructors (cont.)


18.3.3 Copy Constructors


18.3.3 Copy Constructors (cont.)


18.3.3 Copy Constructors (cont.)

Invoked:

18.3.4 Field Initializer Lists

Member data may be assigned in a field initializer list.

18.3.4 Field Initializer Lists (cont.)

class Employee
{
public:
   Employee(String employee_name, double initial_salary);
   . . .
private:
   String name;
   double salary;
};

Employee::Employee(String employee_name, double initial_salary)
   : name(employee_name), salary(initial_salary)
{
}

18.3.4 Field Initializer Lists (cont.)


18.3.4 Field Initializer Lists (cont.)


18.3.4 Field Initializer Lists (cont.)


18.3.5 Assignment Operators


18.3.5 Assignment Operators (cont.)


18.4 Destructors


18.4 Destructors (cont.)

Syntax 17.2 : Overloading Operator Definition
ClassName::~ClassName()
{
	 statements
}
Example:
String::~String()
{
   delete[] buffer;
}
Purpose: Perform any housekeeping tasks that should be performed before an object is deleted.

18.4 Virtual Destructors (cont.)


18.4 Virtual Destructors (cont.)


18.4 (cont.) "The Big 3" (revisit)

The "Big 3":

18.4.1 The Class auto_ptr

See also: Advanced Topic 18.2 - Overloading the memory management operators.

18.5 Reference Counting


18.5 Reference Counting


18.5 Reference Counting (cont.)


18.5 Example: Reference Counting

Consider our String class: change the semantics for the assignment of strings so that two strings would share a common internal data buffer:


18.5 Example: Reference Counting (sharedString.cpp)


18.5 Reference Counting

Summary: Note:

18.6 Case Study: Matrices

Extend the matrix from 17.11:

18.6 Case Study: Matrices (matrix2.h)


18.6 Case Study: Matrices (matrix2.cpp)


18.6 Case Study: Matrices, (matrixtest2.cpp)


Chapter Summary


  1. Memory is divided into four areas
  2. Pointers can refer to memory in any of the four areas
  3. Initialization errors can occur in any of the four area
  4. Stack-based memory is tied to function entry and exit
  5. Simple objects can be sliced. Use references or pointers
  6. C'tors tie memory allocation with object initialization. Copy c'tors create copies of objects
  7. D'tors return resources when an object is deallocated. The "Big 3"
  8. Reference counts can be used to track shared resources