malloc
or calloc
functions, and deallocated by the free
function. In C++, new memory is usually allocated by the new
operator and deallocated by the delete
or the delete
[]
operator. The problem with memory leaks is that they accumulate over time and, if left unchecked, may cripple or even crash a program. We have taken extensive steps to eliminate memory leaks in the Ptolemy software environment by following the guidelines below and by tracking memory leaks with Purify (a commercial tool from Pure Software Inc.).
Another common mistake is overwriting a variable containing dynamic memory without freeing any existing memory first. For example, assume that thestring
is a data member of a class, and in one of the methods (other than the constructor), there is the following statement:
delete
is not necessary in a class's constructor because the data member would not have been allocated previously.
In writing Ptolemy stars, the delete
operator should be applied to variables containing dynamic memory in both the star's setup and destructor methods. In the star's constructor method, the variables containing dynamic memory should be initialized to zero. By freeing memory in both the setup and destructor methods, one covers all possible cases of memory leaks during simulation. Deallocating memory in the setup method handles the case in which the user restarts a simulation, whereas deallocating memory in the destructor covers the case in which the user exits a simulation. This includes the cases that arise when error messages are generated. For an example implementation, see the implementation of the SDFPrinter
star given in Section
2.6.
savestring
. Occasionally, dynamic memory is being used when instead local memory could have been used. For example, if a variable is only used as a local variable inside a method or function and the value of the local variable is not returned or passed to outside the method or function, then it would be better to simply use local memory. For example,
localstring
. The code should be rewritten to use either the StringList
or InfString
class, e.g.,StringList
and InfString
can manage the construction of strings of arbitrary size. When a function or method exits, the destructors of the StringList
and InfString
variables will automatically be called which will deallocate their memory. Casts have been defined that will convert StringList
to a const
char*
string and InfString
to a const
char*
or a char*
string, so that instances of the StringList
and InfString
classes can be passed as is into routines that take character array (string) arguments. A good example of using the StringList
class is in the function compile
in the file $PTOLEMY/src/pigilib/pigiLoader.cc. A simpler example from the same file is the noPermission
function which builds up an error message into a single string:errAdd
function takes a const char*
argument, so sl
will converted automatically to a const char*
string by the C++ compiler.Instead of using the new and delete operators, it is tempting to use constructs like
buflen
is a variable, because the compiler will automatically handle the deallocation of the memory. Unfortunately, this syntax is a Gnu extension and not portable to other C++ compilers. Instead, the StringList
and InfString
classes should be used, as the previous example involving localstring
illustrates.Sometimes the return value from a routine that returns dynamic memory is not stored, and therefore, the pointer to the dynamic memory gets lost. This occurs, for example, in nested function calls. Code such as
hashstring
function, which returns dynamic memory. This dynamic memory, however, should not be deallocated because it may be reused by other calls to hashstring
. It is the responsibility of the hashstring
function to deallocate any memory it has allocated.