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