If `new int` returns an `int*`, then why doesn't `new int[n]` return an `int**`?

Viewed 286

I am puzzled how both new int and new int[n] return an int*. Why doesn't the latter return an int**?

Here is some context: refer to the variable data below in a snippet from Goodrich, Tamassia, and Mount's 2nd ed. Data Structures and Algs in C++ textbook:

class Vect {
   public:
      Vect(int n);
       ~Vect();
      // ... other public members omitted
   private:
      int* data;
      int size;
};
    
Vect::Vect(int n) {
    size = n;
    data = new int[n];
}
    
Vect::~Vect() {
    delete [] data;
}
2 Answers

(answers contains simplifications for the sake of explanations)

In C, a pointer to an array of ints would be of type int**, if I am not mistaken.

You are mistaken. In C it also would be int*.

When you declare: int foo[] = { 1, 2, 3 }, the name of array (foo) can be treated as pointer to its first element (1). The pointer to int is int*.

Additionally, why are we calling delete[] instead of delete, to delete an int* (data)?

delete deletes single object. delete [] removes dynamic array.

new int[n] cannot return a result of type int** because an int** value has to point to an object of type int* (a pointer object).

new int[n] allocates memory for an array of n objects, each of which is of type int. It does not create a pointer object.

The int* value it returns points to the initial (0th) element of the allocated array. Other elements of the array can be accessed by pointer arithmetic.

It could have been defined to yield a result of type int (*)[n], which is a pointer to an array of n int elements, except that (a) C++ doesn't permit arrays with non-constant bounds, and (b) even for something like int (*)[4], it's less convenient that int*.

C++, like its ancestor language C, treats arrays as second-class citizens. Array expressions, in most but not all contexts, are "converted" (adjusted at compile time) to pointer expressions, pointing to the initial element of the array object, and array elements are accessed using pointer arithmetic. (The indexing operator a[i] is syntactic sugar for *(a+i)).

Yes, it can all be confusing and counterintuitive.

Recommended reading: Section 6 of the comp.lang.c FAQ (most of it applies to both C and C++).

Related