The storage class of a C++ variable determines its "lifetime", how long it remains in the computer's memory.
The memory of a C++ program running on Unix consists of the following sections:
The text segment (a.k.a. the code segment) contains the executable instructions of the program. The remaining sections of memory are used to store the program's data. Where a variable is stored depends on its storage class.
C++ variables essentially belong to one of three storage classes:
Automatic storage: Automatic variables are stored on the stack. Each time a function is entered, a stack-frame is allocated and is used to hold the values of all automatic variables declared in the function. The stack frame is also used to hold addressing information that is used to tell the CPU how to "get back" to the calling function. When the function is exited, the stack-frame is deallocated and the variables it contained are destroyed.
In C++, all block scope variables (including function parameters) are automatic storage by default.
Static storage: Static variables are stored in the static data region of the C++ program. Static variables are allocated and initialized before the program starts running and remain in memory as long as the program is running, regardless of whether or not they are currently in scope.
Static variables that are explicitly initialized to a value other than zero in the program's source code are stored in the initialized data segment (a.k.a. the data segment). Static variables that are explicitly initialized to zero or that do not have explicit initialization in the program's source code are stored in the uninitialized data segment (a.k.a. the BSS segment, named for an old assembler pseudo-operation called "Block Started by Symbol"). They are initialized to zero before the program begins running.
In C++, file scope variables are static storage by default. A block scope variable (but not a function parameter) or a data member of a class may be made static storage by placing the keyword static
at the front of the variable's declaration.
For example, in the following function the local variable num_calls
has been declared to be static
. That means it will be initialized to 0 before the program begins running and will retain its value throughout the execution of the program.
void count_calls()
{
static int num_calls = 0; // Value of num_calls is retained between each function call
cout << "The count_calls function has been called " << ++num_calls << " time(s)\n";
}
Without the static
keyword, the variable num_calls
would be automatic storage. As such, it would be created and initialized to 0 each time the function was entered and destroyed when the function exited.
Dynamic storage: Dynamic variables are stored on the free store. They are allocated at run time using the C++ operators new
and new[]
. Dynamic variables exist until they are explicitly de-allocated using the C++ operators delete
and delete[]
or the program ends. Managing dynamic storage will be covered in detail later in the semester.