C++ Memory Model

(the portions of memory are sometimes called segments)


Code Segment
where the instructions that comprise
the program are

Data Segment
static and global variables


Stack Segment

consider the code fragment:

  main(){
    fcnA();
    fcnB();
  }

  fcnA(){
    fcnC();
  }

  fcnB(){
  }

  fcnC(){
  }

Each invocation (call, at run time)
must keep track of

These are bundled into a group called
an activation record (AR) or stack frame.


An AR

A stack is the correct organization.


Heap Segment (Free Store)

C++ expects the programmer to free memory
when it is no longer needed.
This allocation and deallocation is called
memory management.

   int * ptrX;     // static
   ptrX = new int; // dynamic

OR

   int * ptrX = new int;
                  |------|
          (heap)  |      |
                  |------|
                     .                  
                     .                  
                  |------|
            ptrX  |      |
       (not heap) |------|


   int * ptrX = new int;
   delete ptrX;



                  |------|
          (heap)  |      |
                  |------|
                     .                  
                     .                  
                  |------|
            ptrX  |      |
       (not heap) |------|

Variable ptrX remains unchanged.


No delete? Called a memory leak.

   int * ptrX = new int;
   .
   .
   ptrX = new int;  // MEMORY LEAK

OR

   int Y = 17;
   int * ptrX = new int; 
   .
   .
   ptrX = &Y;      // MEMORY LEAK
                  |------|
          (heap)  |      |
                  |------|
                  |      |
                  |------|
                     .                  
                     .                  
                  |------|
            ptrX  |      |
       (not heap) |------|


   int * ptr = new int;
   delete ptr;
   delete ptr;  // BAD!

Not defined: what happens if use delete
on already freed space.



   int X = 12;  // static allocation
   int * ptr = &X;
   delete ptr;  // BAD!

Cannot free statically allocated memory.


Dynamic allocation of arrays works fine. . .

   int * ptrAr;
   ptrAr = new int[8];
   .
   .
   delete [] ptrAr;  // frees up the
                     // entire array's space

Pair new/delete appropriately:

new type [] with delete []

AND

new type with delete


MEMORY LEAK!

   int fcn (. . .) {
      char *ptr;
      ptr = new char;
      .
      .
   }

                  |-------|
          (heap)  |       |
                  |-------|
                  |       |
                  |-------|
                     .                  
                     .                  
                  |-------|
         (stack)  |       |  fcn's AR
                  |-------|
                  |ptr    |
                  |-------|

Functions

There are 3 parts to any function:

  1. prototype
  2. definition
  3. call

Prototype

Allows the compiler to specify an AR with

                      formal arguments
rtntype  fcnName (type id1, type id2, ... );

The id is optional within the prototype.


Function Definition


                      formal arguments
rtntype  fcnName (type id1, type id2, ... ) {

     // code goes here

}

Simple example:
with a call, and a call-by-value parameter


  void fcn(int X);  // prototype

  void fcn(int X) {  // definition
     X = 20;
  }

    .
    .

  Y = 10;
  fcn(Y);      // call

Arguments that are arrays are special.


// prototype
int sum(int ar[], int numelems); 


// definition
int sum(int ar[], int numelems) {
   // code here to sum the elements
}
       
    .
    .

int Ar[25];
total = sum(Ar, 25);      // call

More on arguments that are arrays:

What is on the stack for the formal
argument int ar[]? Could be:

Answer: The C++ compiler uses/passes
int * ar


Copyright © Karen Miller, 2007