Note that the critical requirement for using delete is to use it with memory allocated by new. This doesn’t mean you have to use the same pointer you used with new; instead, you have to use the same address:
int * ps = new int; // allocate memory
int * pq = ps; // set second pointer to same block
delete pq; // delete with second pointer
Ordinarily, you won’t create two pointers to the same block of memory because that raises the possibility that you will mistakenly try to delete the same block twice. But as you’ll soon see, using a second pointer does make sense when you work with a function that returns a pointer.
Using new to Create Dynamic Arrays
If all a program needs is a single value, you might as well declare a simple variable because that is simpler, if less impressive, than using new and a pointer to manage a single small data object. More typically, you use new with larger chunks of data, such as arrays, strings, and structures. This is where new is useful. Suppose, for example, you’re writing a program that might or might not need an array, depending on information given to the program while it is running. If you create an array by declaring it, the space is allocated when the program is compiled. Whether or not the program finally uses the array, the array is there, using up memory. Allocating the array during compile time is called
For now, we’ll look at two basic matters concerning dynamic arrays: how to use C++’s new operator to create an array and how to use a pointer to access array elements.
Creating a Dynamic Array with new
It’s easy to create a dynamic array in C++; you tell new the type of array element and number of elements you want. The syntax requires that you follow the type name with the number of elements, in brackets. For example, if you need an array of 10 ints, you use this:
int * psome = new int [10]; // get a block of 10 ints
The new operator returns the address of the first element of the block. In this example, that value is assigned to the pointer psome.
As always, you should balance the call to new with a call to delete when the program finishes using that block of memory. However, using new with brackets to create an array requires using an alternative form of delete when freeing the array:
delete [] psome; // free a dynamic array
The presence of the brackets tells the program that it should free the whole array, not just the element pointed to by the pointer. Note that the brackets are between delete and the pointer. If you use new without brackets, you should use delete without brackets. If you use new with brackets, you should use delete with brackets. Earlier versions of C++ might not recognize the bracket notation. For the ANSI/ISO Standard, however, the effect of mismatching new and delete forms is undefined, meaning that you can’t rely on some particular behavior. Here’s an example:
int * pt = new int;
short * ps = new short [500];
delete [] pt; // effect is undefined, don't do it
delete ps; // effect is undefined, don't do it
In short, you should observe these rules when you use new and delete:
• Don’t use delete to free memory that new didn’t allocate.
• Don’t use delete to free the same block of memory twice in succession.
• Use delete [] if you used new [] to allocate an array.
• Use delete (no brackets) if you used new to allocate a single entity.
• It’s safe to apply delete to the null pointer (nothing happens).
Now let’s return to the dynamic array. Note that psome is a pointer to a single int, the first element of the block. It’s your responsibility to keep track of how many elements are in the block. That is, because the compiler doesn’t keep track of the fact that psome points to the first of 10 integers, you have to write your program so that it keeps track of the number of elements.
Actually, the program does keep track of the amount of memory allocated so that it can be correctly freed at a later time when you use the delete [] operator. But that information isn’t publicly available; you can’t use the sizeof operator, for example, to find the number of bytes in a dynamically allocated array.
The general form for allocating and assigning memory for an array is this: