www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Array of array

reply RenatoL <rexlen gmail.com> writes:
auto r = new int[][5];
this is ok

auto r = new int[][];
this is not ok
Error: new can only create structs, dynamic arrays or class objects
, not int[][]'s

why?
Jan 02 2012
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/02/2012 11:04 PM, RenatoL wrote:
 auto r = new int[][5];
 this is ok

 auto r = new int[][];
 this is not ok
 Error: new can only create structs, dynamic arrays or class objects
 , not int[][]'s

 why?

What would you expect the code to do? What you are trying to achieve is similar to: class Array(T){this(size_t length){...}} auto r = new Array!(Array!int); // error: missing constructor argument
Jan 02 2012
next sibling parent reply RenatoL <rexlen gmail.com> writes:
Just curious... the answer of the compiler it's a bit unclear to
me...

T[] is a dynamic array of type T.
T[][] is a dynamic array of T[]. But this doesn't work. Why?
Jan 02 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/02/2012 11:21 PM, RenatoL wrote:
 Just curious... the answer of the compiler it's a bit unclear to
 me...

 T[] is a dynamic array of type T.
 T[][] is a dynamic array of T[]. But this doesn't work. Why?

It does work. Why do you think it does not? T[] a; // ok T[][] b; // ok auto c = new T[5]; // ok auto d = new T[][5]; // ok auto e = new T[]; // fail, nonsensical auto f = new T[][]; // fail, nonsensical
Jan 02 2012
next sibling parent reply Mafi <mafi example.org> writes:
Am 02.01.2012 23:33, schrieb Timon Gehr:
 On 01/02/2012 11:21 PM, RenatoL wrote:
 Just curious... the answer of the compiler it's a bit unclear to
 me...

 T[] is a dynamic array of type T.
 T[][] is a dynamic array of T[]. But this doesn't work. Why?

It does work. Why do you think it does not? T[] a; // ok T[][] b; // ok auto c = new T[5]; // ok auto d = new T[][5]; // ok auto e = new T[]; // fail, nonsensical auto f = new T[][]; // fail, nonsensical

Here we come to an interesting point I often thought of. How do you allocate a T[] itself (so you get a T[]*) or a ClassType reference (so you get a ClassType*) on the heap (without casting)? As far as I know it's not possible with new. new T[n] is of type T[]. new T[]* is of type T[]**. new ClassType is of type ClassType. new ClassType* is of type ClassType**. Is this a Hole of new? Mafi
Jan 02 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/03/2012 12:02 AM, Mafi wrote:
 Am 02.01.2012 23:33, schrieb Timon Gehr:
 On 01/02/2012 11:21 PM, RenatoL wrote:
 Just curious... the answer of the compiler it's a bit unclear to
 me...

 T[] is a dynamic array of type T.
 T[][] is a dynamic array of T[]. But this doesn't work. Why?

It does work. Why do you think it does not? T[] a; // ok T[][] b; // ok auto c = new T[5]; // ok auto d = new T[][5]; // ok auto e = new T[]; // fail, nonsensical auto f = new T[][]; // fail, nonsensical

Here we come to an interesting point I often thought of. How do you allocate a T[] itself (so you get a T[]*) or a ClassType reference (so you get a ClassType*) on the heap (without casting)? As far as I know it's not possible with new. new T[n] is of type T[]. new T[]* is of type T[]**. new ClassType is of type ClassType. new ClassType* is of type ClassType**. Is this a Hole of new? Mafi

Yes, but you can use (new T[][1]).ptr; to allocate T[] itself (and get a T[]*). Maybe new T[] should be interpreted as allocating a T[] and give back a T[]*.
Jan 02 2012
parent reply bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:

 Interesting trivia, the compiler actually transforms the following:
 
 struct S
 {
   int x;
 }
 
 auto s = new S;
 
 into this:
 
 auto s = (new S[1]).ptr;
 
 Found that out when revamping the array allocation code.  It's one thing  
 that still bugs me because this means s will be initialized as an  
 appendable array when it doesn't have to be.

What are the disadvantages caused by this? If the disadvantages are significant is this improvement in Bugzilla as enhancement request? Struct heap allocations are important, they are a basic part of D programming. Bye, bearophile
Jan 07 2012
parent reply bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:

 Wasted space.  An appendable array requires extra space at the end of the  
 block to store the 'used' length.
 
 If the disadvantages are significant is this improvement in Bugzilla as  
 enhancement request?

It's not in bugzilla, but it's strictly a performance thing, I don't think the current method causes any harm, it's just not as optimal as it could be.

Thank you for your answers. This has to go in Bugzilla. You are more qualified than me to write it. But if you don't want to write it, I'll write it myself. Bye, bearophile
Jan 07 2012
parent bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:

 http://d.puremagic.com/issues/show_bug.cgi?id=7243

Thank you :-) I think in Bugzilla there is space for few performance-related enhancement requests too, if they are about very common/important parts of the language :-) Bye, bearophile
Jan 07 2012
prev sibling parent reply RenatoL <rexlen gmail.com> writes:
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.
Jan 02 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
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.
Jan 02 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/03/2012 12:46 AM, Matej Nanut wrote:
 On 3 January 2012 00:27, Timon Gehr <timon.gehr gmx.ch
 <mailto:timon.gehr 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. }
Jan 02 2012
prev sibling next sibling parent Matej Nanut <matejnanut gmail.com> writes:
--00151758b3082221a404b59434b8
Content-Type: text/plain; charset=UTF-8

On 3 January 2012 00:27, Timon Gehr <timon.gehr 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? --00151758b3082221a404b59434b8 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <br><br><div class=3D"gmail_quote">On 3 January 2012 00:27, Timon Gehr <spa= n dir=3D"ltr">&lt;<a href=3D"mailto:timon.gehr gmx.ch">timon.gehr gmx.ch</a=
&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 =

<div class=3D"HOEnZb"><div class=3D"h5">On 01/03/2012 12:03 AM, RenatoL wro= te:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> I have:<br> <br> auto r =3D new int[][];<br> <br> Error: new can only create structs, dynamic arrays or class objects<br> , not int[][]&#39;s<br> <br> while<br> <br> auto r =3D new int[][3];<br> <br> is ok.<br> </blockquote> <br></div></div> new int[][3] is an alternate form of new int[][](3); new int[][3] allocates= an int[][] with 3 default-initialized elements.<br> </blockquote></div><br>I assume `int[][] sth;` does what RenatoL wants to a= ccomplish by `auto sth =3D new int[][];`. I do however have a question:<br>= is `auto sth =3D new int[][5];` the same as `int[][5] sth;`? If not, what i= s the difference?<br> <br> --00151758b3082221a404b59434b8--
Jan 02 2012
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 02 Jan 2012 18:30:52 -0500, Timon Gehr <timon.gehr gmx.ch> wrote:

 On 01/03/2012 12:02 AM, Mafi wrote:
 Am 02.01.2012 23:33, schrieb Timon Gehr:
 On 01/02/2012 11:21 PM, RenatoL wrote:
 Just curious... the answer of the compiler it's a bit unclear to
 me...

 T[] is a dynamic array of type T.
 T[][] is a dynamic array of T[]. But this doesn't work. Why?

It does work. Why do you think it does not? T[] a; // ok T[][] b; // ok auto c = new T[5]; // ok auto d = new T[][5]; // ok auto e = new T[]; // fail, nonsensical auto f = new T[][]; // fail, nonsensical

Here we come to an interesting point I often thought of. How do you allocate a T[] itself (so you get a T[]*) or a ClassType reference (so you get a ClassType*) on the heap (without casting)? As far as I know it's not possible with new. new T[n] is of type T[]. new T[]* is of type T[]**. new ClassType is of type ClassType. new ClassType* is of type ClassType**. Is this a Hole of new? Mafi

Yes, but you can use (new T[][1]).ptr; to allocate T[] itself (and get a T[]*). Maybe new T[] should be interpreted as allocating a T[] and give back a T[]*.

Interesting trivia, the compiler actually transforms the following: struct S { int x; } auto s = new S; into this: auto s = (new S[1]).ptr; Found that out when revamping the array allocation code. It's one thing that still bugs me because this means s will be initialized as an appendable array when it doesn't have to be. -Steve
Jan 07 2012
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sat, 07 Jan 2012 13:29:25 -0500, bearophile <bearophileHUGS lycos.com>  
wrote:

 Steven Schveighoffer:

 Interesting trivia, the compiler actually transforms the following:

 struct S
 {
   int x;
 }

 auto s = new S;

 into this:

 auto s = (new S[1]).ptr;

 Found that out when revamping the array allocation code.  It's one thing
 that still bugs me because this means s will be initialized as an
 appendable array when it doesn't have to be.

What are the disadvantages caused by this?

Wasted space. An appendable array requires extra space at the end of the block to store the 'used' length.
 If the disadvantages are significant is this improvement in Bugzilla as  
 enhancement request?

It's not in bugzilla, but it's strictly a performance thing, I don't think the current method causes any harm, it's just not as optimal as it could be. -Steve
Jan 07 2012
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sat, 07 Jan 2012 14:24:19 -0500, bearophile <bearophileHUGS lycos.com>  
wrote:

 Steven Schveighoffer:

 Wasted space.  An appendable array requires extra space at the end of  
 the
 block to store the 'used' length.

 If the disadvantages are significant is this improvement in Bugzilla  

 enhancement request?

It's not in bugzilla, but it's strictly a performance thing, I don't think the current method causes any harm, it's just not as optimal as it could be.

Thank you for your answers. This has to go in Bugzilla. You are more qualified than me to write it. But if you don't want to write it, I'll write it myself.

http://d.puremagic.com/issues/show_bug.cgi?id=7243 -Steve
Jan 07 2012
prev sibling next sibling parent reply Manfred Nowak <svv1999 hotmail.com> writes:
RenatoL wrote:

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

There is an error in the error message: new can only create _static_ arrays. -manfred
Jan 02 2012
parent Manfred Nowak <svv1999 hotmail.com> writes:
Jonathan M Davis wrote:

 new is used for creating _dynamic_ arrays, not static arrays.

Correct, my fault. I meant something like "statically initialized dynamic", because `new' currently needs an `uint' number to allocate some space for the elements of the outermost array. The posting shows, that it is correct not to initialize the length of a dynamic array by some number (even zero would be wrong). Despite of this: the errormessage is missing an important point. -manfred
Jan 02 2012
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, January 02, 2012 23:49:36 Manfred Nowak wrote:
 RenatoL wrote:
 Error: new can only create structs,
 dynamic arrays or class objects, not int[][]'s

There is an error in the error message: new can only create _static_ arrays.

Um no. new is used for creating _dynamic_ arrays, not static arrays. Static arrays normally go on the stack. int[5] staticArray; auto dynamicArray = new int[](5); - Jonathan M Davis
Jan 02 2012