|
Charles Leggett LBNL (510) 495-2930
|
Last Update: |
|
Before you do any coding, please read the following coding
guidelines: |
When a C++ program starts, 5 distinct areas of memory are
created. These are:
The StackThe stack is where local variables and function parameters reside. It is called a stack because it follows the last-in, first-out principle. As data is added or pushed to the stack, it grows, and when data is removed or popped it shrinks. In reality, memory addresses are not physically moved around every time data is pushed or popped from the stack, instead the stack pointer, which as the name implies points to the memory address at the top of the stack, moves up and down. Everything below this address is considered to be on the stack and usable, whereas everything above it is off the stack, and invalid. This is all accomplished automatically by the operating system, and as a result it is sometimes also called automatic memory. On the extremely rare occasions that one needs to be able to explicitly invoke this type of memory, the C++ key wordauto can be used. Normally, one declares variables on the
stack like this:
Variables that are declared on the stack are only valid within the
scope of their declaration. That means when the function func()
listed above returns, i and x will no longer be
accessible or valid.There is another limitation to variables that are placed on the stack: the operating system only allocates a certain amount of space to the stack. As each part of a program that is being executed comes into scope, the operating system allocates the appropriate amount of memory that is required to hold all the local variables on the stack. If this is greater than the amount of memory that the OS has allowed for the total size of the stack, then the program will crash. While the maximum size of the stack can sometimes be changed by compile time parameters, it is usually fairly small, and nowhere near the total amount of RAM available on a machine.
The Global NamespaceThe fact that variables on the stack disappear as soon as they go out of scope limits their usefulness. Another class of variables exist that do not have this limitation. These are global and namespace variables, static class members, and static variables in functions. Global variables are accessible throughout the program, and are declared in this manner:
The output of this program will be:
i in main: 5 j in main: 7 global j: 3 f in func: 20.0 global f: 10.0Local variables take precedence over global variables of the same name. If both are defined as shown above for the variable int
j, then j refers to the local copy, whereas
::j refers to the global copy.Despite their attraction, global variables are very dangerous, and should be avoided. The permit uncontrolled access to data, which runs counter to the object nature of C++ programming.
When data is common to, or must be shared amongst all instances of a
class, one can use
Here the integer MuonsInEvent is static, and common to all
instances of the Muon class. The declaration of
MuonsInEvent does not define an integer, and no storage space
is set aside. So the variable must be defined and initialized, as it
is on the 13th line. Since it was declared public, it can then
be accessed directly in main() by its class reference, and not
by a reference to a specific instance of the class. If one wishes to
restrict access to the static variable, as is often wise, it can be
declared private, and then only member functions of the class
can access it, just like a normal private variable.
Member functions of a class can also be declared
Note that static member functions do not have a this pointer,
and therefore cannot be declared const. And since member data
variables are accessed in member functions using the this
pointer, static member functions cannot access any non-static member
variables. Furthermore, static variables should not be used as a pseudo-global variable. While there are certain distinct implementations where they are mandated, static variables and functions should be used with caution. If you find yourself using them frequently, there is a significant chance that your design is at fault. This is especially true for Level 3 code, as tools are instantiated at the beginning of the run, and thus their members are easily accessible at any time thereafter.
The Free StoreThe main problem with local variables, is that they don't persist. As soon as a function returns, all the local variables declared within it vanish. While it is possible to get around this with global variables, this is not wise. Instead, one can make use of the free store, or heap as it is often called.
Variables and objects are declared on the heap using the keyword
Once you're done with something declared on the heap, it must be
explicitly freed using the keyword delete. If this is not
done, and the pointer is reassigned, a memory leak occurs. The
original memory becomes unavailable, and cannot be accessed. If this
is done many times, then eventually all the available memory will be
gobbled up, and your program will crash.The heap is where the vast majority of your variables should be declared. This is because the heap is far larger than the stack, and once something is placed there, it won't disappear until you tell it to, avoiding the use of those nasty global variables.
Note that most memory managers are greedy: even when memory is
properly freed with An interesting note: on the SGI, the preceding paragraph is correct. However, it seems that the memory manager in Linux is more intelligent. When space on the heap is deleted in Linux, the allocated memory is returned to the operating system. Depending on the application, this can be a good or a bad thing.
When checking for an out of memory condition, one can get a little
fancier, and make use of the
If you want your code to follow the standard C syntax and return a
null pointer when new fails, then the form
new(nothrow) must be used:
When using the KAI compiler, if the compiler parameter
--no_exceptions is used, new is implemented
as new(nothrow). Currently, g++ is not smart enough to do
this.
|