Creating an array in the run-time stack
Statement
int A[10];creates an array of ints within the current function's run-time stack frame and names it A. In general, the form is T name[size];where T is the type of each variable in the array, name is the array's name and size is the number of items. For example, double stuff[100];creates an array called stuff of size 100, where each variable in the array has type double. |
Creating an array in the heap
If you want to use an array after the function that created
it returns, allocate that array in the heap, not in the
run-time stack. Expression new T[size]
allocates a new array with size variables in it,
each of type T.
Remember that an array is treated just like a pointer to the first thing in a chunk of memory. So expression new int[25] has type int*. Statement int* A = new int[25];allocates a new chunk of 25 ints and stores a pointer to the first one of those ints into variable A. The size can be given by any expression that yields an integer. For example, if you already have an integer variable called n that currently holds 50, then double* B = new double[n];allocates a chunk of 50 doubles. |
Watch out: new int(25)
To allocate an array, use square brackets around the size. Unfortunately, expression new int(25) allocates one variable and stores 25 in it. That is really not a good language feature, but we have to live with it and watch out for it. |
delete [ ] p;
If you allocate an array (using brackets with new), then, when you delete that array, write an empty set of square brackets after delete. It is up to you to know whether you are deallocating an array of just one thing. |
Watch out: delete an entire array
Never try to delete just a part of an array. Your only option is to delete the entire array. If you try to delete part of an array, you will corrupt the heap manager. |
Watch out: never delete an array that is in the run-time stack
You only delete an array that is in the heap. If you do
int A[100]; ... delete [] A;you will corrupt the heap manager. |
Watch out: do not misuse the run-time stack
Consider the following attempt to allocate an array.
int* allocArr(int n) { int A[n]; return A; }The compiler will not give you an error on this. A is an array of integers (type int*), so the correct type of thing is returned. But the returned pointer is pointing into the stack frame of allocArr. As soon as allocArr returns, that becomes a dangling pointer. To allocate an array that you need to keep using after the function returns, use new. |
The preceding example creates arrays of size 10
and 100. But if you need to create an array
of a fixed size, always make the size a
named constant. For example,
write
const int nameMax = 100;and, to create an array, write char name[nameMax];You want to have a single point of modification. Wherever you need to refer to nameMax, write nameMax, not 100. If you decide to change nameMax to 200, you should only need to change the line that defines constant nameMax. |
In C++, you can create an array either in the frame of the current function or in the heap. Use expression new int[n] to allocate an array of n integers in the heap. Its value is the address of the first of those integers, so new int[n] has type int*.
To delete an array A that was allocated in the heap, say
delete [] A;
If you do not know how large an array needs to be, make its size a named constant so that the size is easy to change by changing the value of that constant.
Write a statement that allocates a new array of 75 characters called frog. The new array should be in the heap. Answer
There is something wrong with the following function. Explain what is wrong.
// makeZeroedArray(n) returns an array with // n items, all set to 0. int* makeZeroedArray(int n) { int A[n]; for(int i = 0; i < n; i++) { A[i] = 0; } return A; }Answer
There is something wrong with the following function. Explain what is wrong.
// makeZeroedArray(n) returns an array with // n items, all set to 0. int* makeZeroedArray(int n) { int* A = new int(n); for(int i = 0; i < n; i++) { A[i] = 0; } return A; }Answer
Suppose array A has been created by
double* A = new double[m];If you are done with array A and want to return it to the heap manager, what statement should you use? Answer
Suppose array A has been created by
double A[m];When the program is done with array A, what should the program do? Answer
The following function tries to read up to 100 integers from the standard input. So it allocates an array of size 100. But that is wasteful if you only actually read a few integers before hitting the end of the file. So this function decides to give the unused portion of the array back to the heap manager. Does that work?
int* readInts() { int* A = new int[100]; int i; for(i = 0; i < 100; i++) { int k = scanf("%i", &(A[i])); if(k != 1) { break; } } if(i < 100) { delete [] A + i; } return A; }Answer
Function readInts() above wants to read some numbers and return an array containing them. If the bad part is removed from it, how would its caller know how many integers were read? Answer
What is the type of expression new long[12]? Answer
There is something wrong with the following function. Explain what is wrong.
// makeZeroedArray(n) returns an array with // n items, all set to 0. int* makeZeroedArray(int n) { int* p = new int[n]; for(int i = 0; i < n; i++) { p[i] = 0; } delete [] p; return p; }Answer
There is something wrong with the following function. Explain what is wrong.
// makeZeroedArray(n) returns an array with // n items, all set to 0. int* makeZeroedArray(int n) { int* p = new int[n]; for(int i = 0; i <= n; i++) { p[i] = 0; } return p; }Answer