5.11.5 Allocating and Deallocating Arrays in the Heap

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 the array. So expression new int[25] has type int*. Statement
  int* A = new int[25];
allocates a new array of 25 ints and stores a pointer to the first one 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 an array 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.

Allocating an array in C (optional)

To allocate an array in the heap in a C program, where new is not available, use malloc, and compute the number of bytes that are needed. For example, C statement
  int* A = (int*) malloc(n*sizeof(int));
is roughly equivalent to C++ statement
  int* A = new int[n];
The difference is that malloc and new sometimes use different heap-management algorithms.


Exercises

  1. Write a statement that allocates a new array of 75 characters called frog. The new array should be in the heap. Answer

  2. 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

  3. 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

  4. 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

  5. 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

  6. 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

  7. What is the type of expression new long[12]? Answer

  8. 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

  9. 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