Memory Allocation: Static and Dynamic


When a variable is defined, a block of memory of a specified size is set aside for this variable throughout its lifetime. For example:

image from book

    int anInt; 

image from book

sets aside enough memory for the variable anInt throughout its scope. This assignment is done each time the program executes this statement. This process is referred to as: static memory allocation

Static memory allocation is wasteful. For example an array may need 10 to 50 elements 99% of the time. For 1% of the time, the array may need 1000 elements. Static memory allocation would require that every time the program ran the statement, the array size must be 1000.

Static memory may be created on the stack or the heap. The location will depend on where in the program, the variable is defined. If the variable is defined globally, then the memory is stored on the heap and therefore available to the program throughout the life of the program. If the variable is defined within a block, it may be defined on the heap or on the stack depending on its storage class.

A better solution type of array needed above would be: dynamic memory allocation where the amount of memory is only assigned when required. The programming language C has several functions to handle dynamic memory allocation including: malloc(), calloc(), realloc() and free(). This type of dynamic memory allocation requires typecasting in order to meet today's needs.

It is not in the spirit of C++ to require typecasting or the use of the function sizeof() as required by these C functions. Further, we will want to create memory dynamically on any data type we create which these functions are not able to do. Therefore C++ has a better way. C++ uses the dynamic memory allocation operators new and delete both of which are extendable to user data types while malloc() and calloc() are not. (For those of you who will study C#, you will meet the operator new again in that language but not the delete operator.)

In C++, to create memory dynamically, we use the operator new when initializing the pointer. For example:

image from book

 int * ptr; ptr = new int; 

image from book

In the first statement ptr is defined to be a pointer to an int. In the second statement on the right side of the assignment: new int creates an unnamed place in memory of type int and returns its address that is therefore assigned to ptr.

It is possible in some cases to initialize the memory at the time of allocating the memory. For example in the statements above, the memory created by new int could have been initialized to 10 as in the following code:

image from book

 int * ptr; ptr = new int(10); 

image from book

The memory created by the operator new is placed on the heap regardless of where within the program it is called and it will remain there until the program removes it or the system shuts down. This memory can be given back to the system using the operator delete. The memory for the pointer ptr will be stored either on the heap or the stack depending on its scope. The operator delete is said to delete the memory to which ptr points or it deallocates the memory to which ptr points.

 Warning:  The operator delete should only be used on memory that has been allocated by the operator new.

The following is an example of how the delete operator is called:

image from book

 delete ptr; 

image from book

After this statement, the memory created by new in the statement above and whose address was assigned to ptr is given back to the system but the pointer variable ptr is still available for use. For example see TESTPTR2.CPP and RENEWPTR.CPP.

It is the programmer's responsibility to use delete to return the dynamically allocated memory to the system. Bugs may be introduced into your SYSTEM by not deleting dynamically allocated memory. See DELETE.CPP In this example, the memory assigned by the first call of the function is not deleted and is therefore still open when the program exits.

These operators can also be used to manage arrays. For example:

image from book

 stuff * ptr = new stuff [SIZE]; 

image from book

defines an unnamed array of variables of data type stuff with SIZE number of elements. This is an example of a dynamic array.

As discussed above, this dynamically generated memory needs to be given back to the system. Either

image from book

 delete [SIZE] ptr; 

image from book

or

image from book

 delete [ ] ptr; 

image from book

will delete the dynamically allocated memory but the pointer ptr is still defined if it is still within its scope and it may be reused after the dynamically allocated memory to which it pointed has been deleted. It is important to note that destroying ptr (i.e. moving the program out of the scope of the pointer) does not destroy the memory to which it points and visa versa.

 Note:  You should check your compiler's manual to see which of the above two forms of deleting array pointers is used. The second method above is the newer form and may not be implemented on your compiler.

 Note:  It is very important to delete the memory that is created dynamically or problems may occur even after the program has ended.

When the dimension of an array is specified at compile time by an integer, the process is referred to as: static binding. It is possible to specify the dimension of the array with a variable using the operator new. This is referred to as: dynamic binding. That is the size of the array is decided dynamically as the program runs. See VARBARAY.CPP

When memory is created by the operator new, the system may not be able to allocate it. Therefore we should test to ensure that memory has been allocated as in the following:

image from book

 int *ptr = NULL; ptr = new int [100]; if (ptr == 0) {     errorfunction(0);     exit(1); } 

image from book

It is important to note that when using dynamic memory allocation to create arrays, it is not possible to initialize the array at definition time.

In the Managed C++ that was introduced in Visual Studio .NET these concepts are handled in an entirely different manner. In this new version of C++, the programmer does not handle returning memory to the system by using delete. This is done automatically by the system. Such an approach is safer and will reduce the problems caused in some programs where the programmer does not handle dynamic memory management in the proper manner.




Intermediate Business Programming with C++
Intermediate Business Programming with C++
ISBN: 738453099
EAN: N/A
Year: 2007
Pages: 142

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net