21A. Ownership of Memory and Memory Faults

Ownership of memory

An operating system (OS) can run several programs at once. A running program is called a process. Each process has been granted some memory by the OS, and the OS keeps careful track of just which parts of memory each process owns; the OS does not allow a process to look at or store anything into memory that it does not own. No process can interfere with any other process.

Within a process, at any given moment, the memory is divided into a few classifications, according to local ownership.

The running program

Obviously, some of a process's memory belongs to the program that is running, and it is normal behavior for a program to fetch and store information using the memory that it owns.

The heap manager

At any given time, some of the memory in the heap belongs to the running program and the rest belongs to the heap manager (HM), which is responsible for allocating and deallocating memory in the heap.

It is worth noting that, from the perspective of the OS, all of the memory in the heap belongs to the processs. The OS has no knowledge of how the HM has divided up a process's heap.

The run-time stack

Some of a process's memory is used for the run-time stack, where memory is allocated and deallocated in small chunks that correspond to frames. The OS only knows the total amount of memory that is allocated in the run-time stack at any given time, not where the boundaries between frames are.

Memory faults

A memory fault occurs when a process either uses memory in an incorrect way or uses memory that does not belong to it, according to the OS. On a Linux system, a memory fault is called a segmentation fault. When a memory fault occurs, the OS terminates the process immediately.

Memory faults are usually caused by:

  1. trying to store or fetch using a null pointer;

  2. trying to modify memory that the OS has marked as read only;

  3. using an array index that is way out of bounds;

  4. trying to store or fetch using a dangling pointer.

The remaining sections on this page describe the first three of the above. The next page describes dangling pointers.

The null pointer

Memory address 0 is called the null pointer; it is owned by the OS, and no process can own it. The null pointer is a way of saying "a pointer to nothing", and is referred to as NULL. For example,

  char* p = NULL;
declares a pointer variable p and makes it hold memory address 0. In diagrams, we will draw a null pointer as follows.

(Optional)

NULL is not really part of C++. It is defined in some library files, including in <cstdio> and <iostream>. Include one of those to get NULL defined.

To get around that unpleasantness, newer versions of C++ define a constant nullptr that means the same thing as NULL but is part of the language. Unfortunately, g++ does not recognize nullptr unless you explicitly request a particular language version. For that reason, please just use NULL.

Read-only memory

Recall that some memory is marked read-only by the OS. A program cannot modify string constants or its own machine-language program. If your program tries to change something in read-only memory, it will get a memory fault. We will see that string constants are actually arrays of characters. Performing

  char* str = "a string constant";
  str[0] = 'b';
causes a memory fault.

Out-of-bounds array index

Consider the following lines.

  int a[10];
  a[10] = 1;
The allowed indices of array a are 0 to 9, and a[10] does not exist. What happens?

There is no automatic check for array bounds errors in C++. You are expected to do those checks yourself. The computer will use the memory that is just after array a. That has unpredictabe effects.

You will probably not get a memory fault from using a[10]. But that does not make it benign. Storing information into a[10] clobbers something; you just don't know what it is.

Memory faults due to running out of memory

If your program runs out of memory, either in the run-time stack or the heap, it will get a memory fault. That is only likely to happen if the program runs amok and starts allocating huge amounts of memory, and nothing can be done to recover from it.

Exercises

  1. What is a memory fault? Answer

  2. If you delete memory and immediately try to use it, do you always get a memory fault? Answer

  3. What is the null pointer? Answer