Array of array

Timon Gehr timon.gehr at gmx.ch
Mon Jan 2 16:21:14 PST 2012


On 01/03/2012 12:46 AM, Matej Nanut wrote:
>
>
> On 3 January 2012 00:27, Timon Gehr <timon.gehr at gmx.ch
> <mailto:timon.gehr at 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.
}






More information about the Digitalmars-d-learn mailing list