0
#include <iostream>
using namespace std;

class CType{
private:
    int val;
public:
    CType(): val(0){}
    CType(int x): val(x){}
    void setVal(int x){ val = x; }
    ~CType(){ cout << val << " is destructed." << endl;} 
};

int main(){
    // CType *t = new CType[10](10); // -1-
    CType (*t)[10] = new CType[10][10]; // -2-
    for(int i = 0; i < 10; ++i){
        for(int j = 0; j < 10; ++j){
            t[i][j].setVal(10 * i + j);
        }
    }
    delete[] t;
    return 0;
}

The above code is a sample I wrote to test new[][] and whether it is possible to initialize instances in dynamic array. My question is:

  1. I intended to create an array of 10 CType instances with val initialized to 10. But this line cannot pass compilation. I have to add a default constructor with no parameter and CType *t = new CType[10]. Is there any way to create an array of instances and invoke constructors with some parameters?

  2. I got puzzled by new int[10][10] which intuitively creates an 10x10 2D array. But I cannot find any official material defining the behavior of new int[][] or new int[][][] etc. Why does new int[10][10] have return type int (*)[10] rather than int** or int[10][10]?

BTW, if I write CType (*t)[10] = new CType[10][10](10), I'll got a compilation error reading A.cpp:13:39: sorry, unimplemented: cannot initialize multi-dimensional array with initializer. Funny, g++ says SORRY.


Update

I'm using g++. But I also tested the code on VS2010. It passed compilation and output the same result as it did in g++.

The variable t in CType (*t)[10] is a pointer which points to an array of 10 CType instances, not an array of 10 CType pointers. So t + 1 points to the place sizeof(CType) * 10 bytes away after t.

The output of my code reveals that the destruct order of delete[] t is 99 to 0. The last element of t + 9 is destructed first.

lzl124631x
  • 4,485
  • 2
  • 30
  • 49
  • What compiler are you using? – Dejan Mar 02 '14 at 08:44
  • 2
    Do you really have to use C arrays ? take a look to STL containers : http://www.cplusplus.com/reference/stl/ – thp9 Mar 02 '14 at 09:18
  • [This FAQ](http://stackoverflow.com/questions/4810664/) covers more than you would ever want to know about arrays in C++, including fancy ASCII art explaining the behavior of various flavors of multi-dimensional arrays. – fredoverflow Mar 02 '14 at 09:50
  • Default constructors never have parameters. That's why they're the default. – Michael Dorst Mar 02 '14 at 09:53
  • @user3134405 No, I don't. I'm familiar with STL, but at this time I just want to better understand the `new` operator and the constructors. – lzl124631x Mar 02 '14 at 13:43

2 Answers2

3

Is there any way to create an array of instances and invoke constructors with some parameters?

There is since C++11:

CType* t = new CType[10] {10, 10, 10, 10, 10, 10, 10, 10, 10, 10};
// ...
delete[] t;

But in general, you are far better of with vectors in C++:

std::vector<CType> t(10);
// ...
// no need to delete anything manually!

I cannot find any official material defining the behavior of new int[][] or new int[][][] etc.

5.3.4 [expr.new] §5 says:

When the allocated object is an array [...], the new-expression yields a pointer to the initial element (if any) of the array.

Note: both new int and new int[10] have type int* and the type of new int[i][10] is int (*)[10]


Why does new int[10][10] have return type int (*)[10] rather than int**

It couldn't be int**, because then a simple delete[] wouldn't be enough.

or int[10][10]?

Because int[10][10] is not a pointer, but new always returns a pointer.

Community
  • 1
  • 1
fredoverflow
  • 256,549
  • 94
  • 388
  • 662
0
  1. There is no way to provide a parenthesed initializer in a new-expression of an array type. Don't use legacy C arrays if you can help it. Standard containers provide a superior alternative.
  2. This is specified by the standard. A new-expression that allocates an array returns a pointer to the first element of the array (5.3.4/1). new int[N][4][5][6] creates an array of N elements, each one of type int[4][5][6]. The pointer to the first element of the array will be returned. It will be of type int(*)[4][5][6], not int**** or somesuch. It is easy to understand if you accept that there are no multidimensional arrays in C++, only arrays of arrays. An element of int x[2][3] has type int[3], not int. Words like pointer to the first element do not automatically generalize to pointer to the first element of the first element etc.
n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243