Dynamic Allocation and Deallocation
Examine the program named NEWDEL.CPP for our first example of the new and delete operators.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | // newdel.cpp #include <iostream.h> struct date { int month; int day; int year; }; main() { int index, * point1, * point2; point1 = & index; * point1 = 77; point2 = new int; * point2 = 173; cout << "The values are " << index << " " << * point1 << " " << * point2 << "\n"; point1 = new int; point2 = point1; * point1 = 999; cout << "The values are " << index << " " << * point1 << " " << * point2 << "\n"; delete point1; float * float_point1, * float_point2 = new float; float_point1 = new float; * float_point2 = 3.14159; * float_point1 = 2.4 * ( * float_point2); delete float_point2; delete float_point1; date * date_point; date_point = new date; date_point - > month = 10; date_point - > day = 18; date_point - > year = 1938; cout << date_point - > month << "/" << date_point - > day << "/" << date_point - > year << "\n"; delete date_point; char * c_point; c_point = new char[37]; delete c_point; c_point = new char[sizeof(date) + 133]; delete c_point; } |
Output of the C Program
1 2 3 | The values are 77 77 173 The values are 77 999 999 10/18/1938 |
The new and delete operators do dynamic allocation and deallocation in much the same manner that malloc() and free() do in your old favorite C implementation.
During the design of C++, it was felt that since dynamic allocation and deallocation are such a heavily used part of the C programming language and would also be heavily used in C++, it should be a part of the language, rather than a library add-on. The new and delete operators are actually a part of the C++ language and are operators, much like the addition operator or the assignment operator. They are therefore very efficient, and are very easy to use as we will see in this example program.
Lines 14 and 15 illustrate the use of pointers in the tradition of C and line 16 illustrates the use of the new operator. This operator requires one modifier which must be a type as illustrated here. The pointer named point2 is now pointing at the dynamically allocated integer variable which exists on the heap, and can be used in the same way that any dynamically allocated variable is used in ANSI-C. Line 18 illustrates displaying the value on the monitor which was assigned in line 17.
Line 20 allocates another new variable and line 21 causes point2 to refer to the same dynamically allocated variable as point1 is pointing to. In this case, the reference to the variable that point2 was previously pointing to has been lost and it can never be used or deallocated. It is lost on the heap until we return to the operating system when it will be reclaimed for further use, so this is obviously not good practice. Note that point1 is deallocated with the delete operator in line 25, and point2 can not actually be deleted. Since the pointer point1 itself is not changed, it is actually still pointing to the original data on the heap. This data could probably be referred to again using point1, but it would be terrible programming practice since you have no guarantee what the system will do with the pointer or the data. The data storage is returned to the free list to be allocated in a subsequent call, and will soon be reused in any practical program.
Since the delete operator is defined to do nothing if it is passed a NULL value, it is legal to ask the system to delete the data pointed to by a pointer with the value of NULL, but nothing will actually happen. It is actually wasted code. The delete operator can only be used to delete data allocated by a new operator. If the delete is used with any other kind of data, the operation is undefined and anything can happen. According to the ANSI standard, even a system crash is a legal result of this illegal operation, and can be defined as such by the compiler writer.
In line 27, we declare some floating point variables. You will remember that in C++ the variables do not have to be declared at the beginning of a block. A declaration is an executable statement and can therefore appear anywhere in a list of executable statements. One of the float variables is allocated within the declaration to illustrate that this can be done. Some of the same operations are performed on these float type variables as were done on the int types earlier.
Some examples of the use of a structure are given in lines 35 through 41 and should be self explanatory.
Finally, since the new operator requires a type to determine the size of the dynamically allocated block, you may wonder how you can allocate a block of arbitrary size. This is possible by using the construct illustrated in line 47 where a block of 37 char sized entities, which will be 37 bytes, is allocated. A block of 133 bytes greater than the size of the date structure is allocated in line 49. It is therefore clear that the new operator can be used with all of the flexibility of the malloc() function which you are familiar with.
The standard functions which you have been using in C for dynamic memory management, malloc(), calloc(), and free(), are also available for use in C++ and can be used in the same manner they were used in C. The new and delete operators should not be intermixed with the older function calls since the results may be unpredictable. If you are updating code with the older function calls, continue to use them for any additions to the code. If you are designing and coding a new program you should use the newer constructs because they are a built in part of the language rather than an add on and are therefore more efficient.
Be sure to compile and execute this program.