On 01/03/2012 12:46 AM, Matej Nanut wrote:


On 3 January 2012 00:27, Timon Gehr <timon.g...@gmx.ch
<mailto:timon.g...@gmx.ch>> wrote:

    On 01/03/2012 12:03 AM, RenatoL wrote:

        I have:

        auto r = new int[][];

        Error: new can only create structs, dynamic arrays or class objects
        , not int[][]'s

        while

        auto r = new int[][3];

        is ok.


    new int[][3] is an alternate form of new int[][](3); new int[][3]
    allocates an int[][] with 3 default-initialized elements.


I assume `int[][] sth;` does what RenatoL wants to accomplish by `auto
sth = new int[][];`. I do however have a question:
is `auto sth = new int[][5];` the same as `int[][5] sth;`? If not, what
is the difference?


It is not the same thing.

First of all, lets get rid of int[][] and use int[] for further reasoning.

int[] is a data structure with two members: 'ptr' and 'length'. 'ptr' is a pointer to the first element of the array, and 'length' indicates how many elements are in the array. int[] does not carry any data on its own: it is only a reference to the data.

int[5] on the other hand is a data structure that contains 5 integers with the indices 0,1,2,3,4.


|ptr|length| <- int[]

|0|1|2|3|4| <- int[5]

An int[5] can be sliced to get an int[]:

void main(){
    int[5] arr1=[0,1,2,3,4];
    int[] arr2 = arr1[];
    // arr2 is now a reference to arr1's data:
    assert(arr2.ptr is &arr1[0] && arr2.length == 5);
    // changing arr2 changes arr1:
    arr2[0] = 5;
    assert(arr1 == [5,1,2,3,4]);
    // assigning int[5] to int[5] copies the data
    int[5] arr3 = arr1;
    assert(arr2.ptr !is &arr1[0]);
    // therefore, changing arr3 lets arr1 intact
    arr3[0] = 0;
    assert(arr1 == [5,1,2,3,4]);
}



void main(){
    int[] arr1; // creates an int[] on the stack with ptr=null and length=0
int[5] arr2; // creates in int[5] on the stack with arr2[i]=0 for i in 0,1,2,3,4
    arr1 = arr2[]; // array slice lets arr1 reference the data of arr2
arr1 = new int[](5); // allocates an int[5] on the heap and lets arr1 reference the newly created data arr1 = new int[5]; // same as the above, syntax carried over from C++/Java
}

With this in mind, it is now possible to understand the difference between int[][5] sth and auto sth = new int[][5]:

void main(){
int[][5] sth1; // creates an int[][5] on the stack (5 default-initialized int[]s) auto sth2 = new int[][5]; // creates an int[][5] on the heap and lets sth2 reference it.
}




Reply via email to