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