Dynamic Data
- In addition to Static variables and Automatic variables, C and C++
provide a third category of
variables known as Dynamic variables
- Any global variable is static, as is any local variable
explicitly declared as static.
The lifetime of a static variable is the lifetime of the
program
- In contrast, an automatic variable - a local variable not
declared as
static is allocated (created) when control reaches its
declaration, and deallocated
(destroyed) when control exits the block in which the variable is
declared
- Dynamic variables are not declared with ordinary variable
declarations; they are explicitly
allocated and deallocated at run time
- Memory allocation is accomplished using the new operator and
deallocation is
accomplished using the delete operator
- When a program requires a variable, it uses new to allocate
the variable. When the
program no longer needs the variable, it uses delete to
deallocate it
- The lifetime of a dynamically allocated variable, therefore, is the
time between the execution
of the new and delete statements
- Consider the following code fragment:
int* intPtr;
char* nameStr;
intPtr = new int; // Creates a variable of type int and stores its
address into intPtr
nameStr = new char[6] // Creates a 6 element char array, and stores the
base address of the array into nameStr
- Normally, the new operator creates an uninitialized variable
of the specified type,
and returns a pointer to it. If, however, there is insufficient memory
available, the new
operator returns a NULL pointer
- Variables created dynamically are said to be on the free
store or
heap
- A dynamic variable is unnamed and cannot be directly accessed. It
must be indirectly accessed
through the pointer returned by new
- Consider the following fragment of code:
#include <string.h>
int* intPtr = new int;
char* nameStr = new char[6];
*intPtr = 365; // Assign 365 to dynamic variable pointed to by
intPtr
strcpy(nameStr, "C++"); // Assign C++ to dynamic array with base address
in nameStr
- Dynamic variables can be destroyed at any time during program
execution. The
delete operator is used for this purpose
- Using the previous example, the dynamic variables may be deallocated
in the following
way:
delete intPtr; // Deallocate the variable pointed to by intPtr
delete [] nameStr; // Deallocate the array whose base address is in
nameStr
- Objects, similar to primitive data types can also be dynamically
created
and destroyed. For example, given a class Date:
/* The following line dynamically creates a Date object
** and initializes the object by implicitly invoking the
** default Date constructor
*/
Date* dateptr = new Date;
/* The following line dynamically creates a Date object
** and explicitly initializes the object by invoking the
** parameterized Date constructor
*/
Date* dateptr = new Date(9,16,1997);
- Arrays of objects can also be dynamically created, however, they
cannot be explicitly initialized. Objects in the array can only be
initialized by implicitly invoking the default constructors. For
example:
/* The following line dynamically creates an array of 10
** Date objects and initializes each object by implicitly invoking the
** default Date constructor of each object
*/
Date* DateArrayPtr = new Date[10];
- Failure to use delete may result in serious memory
leak
problems
- Consider the following fragment of code:
int* intPtr1 = new int;
int* intPtr2 = new int;
*intPtr2 = 44;
*intPtr1 = *intPtr2;
intPtr1 = intPtr2;
delete intPtr2;
The above fragment of code results in two typical problems - memory leaks,
and dangling pointers.
In the fifth statement, intPtr1 is assigned a new address,
thereby, making the previous
dynamic variable inaccessible. This causes a memory leak. In the sixth
statement, the deallocation
of the variable pointed to by intPtr2 results in intPtr1
becoming a dangling
pointer
- Both problems can be eliminated by deallocating intPtr1
before assigning it a new
address, and by setting intPtr1 to NULL after deallocating
intPtr2