Thread overview
Help with multi-dimentional array
Jul 09, 2008
Era Scarecrow
Jul 09, 2008
Era Scarecrow
Jul 09, 2008
Koroskin Denis
Jul 09, 2008
Era Scarecrow
Jul 09, 2008
BCS
Jul 09, 2008
torhu
Jul 10, 2008
Koroskin Denis
July 09, 2008
i've tried to make a multi-dimentional array, using a struct as a container within a class. However when i try to compile it, it complains i'm not using a constant. Rather than do the long way around, is there something i'm doing wrong?

class something{
    struct xyz{
    //something
    }

    xyz[][] abc;    //declared as multi-dimentional array

    void aFunction(int left, int right)
    {
        abc = new xyz[left][right];    //error needs a const

    //work with abc afterwards
    }

}

I'd rather not have to do it this way, although it works.

abc.length=left;
for(int cnt; cnt < left; cnt++)
    abc[cnt].length=right;



Era
July 09, 2008
"Era Scarecrow" <rtcvb32@yahoo.com> wrote in message news:g538vm$2391$1@digitalmars.com...

>        abc = new xyz[left][right];    //error needs a const

Just a little weirdness.  When you write "new xyz[5]" it's actually sugar for "new xyz[](5)".  Think of it like a class -- "new Type(Params)".

For multidimensional arrays, just write

abc = new xyz[][](left, right);

It does exactly the same as the much more verbose loop. :)


July 09, 2008
Jarrett Billingsley Wrote:

> "Era Scarecrow" <rtcvb32@yahoo.com> wrote in message news:g538vm$2391$1@digitalmars.com...
> 
> >        abc = new xyz[left][right];    //error needs a const
> 
> Just a little weirdness.  When you write "new xyz[5]" it's actually sugar for "new xyz[](5)".  Think of it like a class -- "new Type(Params)".
> 
> For multidimensional arrays, just write
> 
> abc = new xyz[][](left, right);
> 
> It does exactly the same as the much more verbose loop. :)
> 

 Ah i see. I don't remember this being covered in any of the books i was reading, and having to go through several loops not only looks ugly; but invites bugs.

 So if i had a 3-dimentional array, i'd assume i'd have to "= new xyz[][][](a,b,c)?" and so on and so forth?

 Then, the question comes up next. If i actually pass a parameter to a class's constructor, would it be....

class xyz{
    this(x,y,z){} //three dimentional points
}

//make two dimentional array taking a 3-dimentional location

 abc = new xyz[][](left, right)(x,y,z);   //is this right??

 Era
July 09, 2008
On Thu, 10 Jul 2008 01:58:46 +0400, Era Scarecrow <rtcvb32@yahoo.com> wrote:

> Jarrett Billingsley Wrote:
>
>> "Era Scarecrow" <rtcvb32@yahoo.com> wrote in message
>> news:g538vm$2391$1@digitalmars.com...
>>
>> >        abc = new xyz[left][right];    //error needs a const
>>
>> Just a little weirdness.  When you write "new xyz[5]" it's actually sugar
>> for "new xyz[](5)".  Think of it like a class -- "new Type(Params)".
>>
>> For multidimensional arrays, just write
>>
>> abc = new xyz[][](left, right);
>>
>> It does exactly the same as the much more verbose loop. :)
>>
>
>  Ah i see. I don't remember this being covered in any of the books i was reading, and having to go through several loops not only looks ugly; but invites bugs.
>
>  So if i had a 3-dimentional array, i'd assume i'd have to "= new xyz[][][](a,b,c)?" and so on and so forth?
>
>  Then, the question comes up next. If i actually pass a parameter to a class's constructor, would it be....
>
> class xyz{
>     this(x,y,z){} //three dimentional points
> }
>
> //make two dimentional array taking a 3-dimentional location
>
>  abc = new xyz[][](left, right)(x,y,z);   //is this right??
>
>  Era

No, you create *an array*, not objects of concrete type. Thus, no constructor is called and an array contains a butch of uninitialized class references. And since no ctor is called, you can't pass any ctor parameters right there.

So you still need a loop to initialize the array properly.
July 09, 2008
Koroskin Denis Wrote:
> No, you create *an array*, not objects of concrete type. Thus, no constructor is called and an array contains a butch of uninitialized class references. And since no ctor is called, you can't pass any ctor parameters right there.
> 
> So you still need a loop to initialize the array properly.

 I see. so after i do the = new xyz[][](left,right), and i wanted to fill in x,y,z i'd have to

// this(x,y,z){} //still this constructor

z=100;
for(int x=0; x<left; x++)
    for (int y=0; y<right; y++)
        xyz[x][y] = new xyz(x,y,z)

 Well, even if we have to do this, creating the basic array is a lot simpler.

 Now let me doublecheck once more. If i DID this.

 abc = new xyz[][](4,4);    //Non-stack and GC handles it, or i can malloc
 abcd [4][4]xyz;    //(Stack / non-Stack) static allocation

 I'll assume that
 1) abcd is an array of 4 pointers that have 4 pointers each
 2) It is not created by the GC, but instead resides on the Stack? (Please confirm)

 If this doesn't make it on the stack, i'll need to know a way that i can, in case i need to make a small array that i don't want to burden the garbage collector. (or worse yet, if i make a module that goes into a kernel that doesn't support GC, i don't want to worry about freeing the memory). Although if i recall it's probably an import. (std.mem.alloca?)

 Era
July 09, 2008
Reply to Era,

> Koroskin Denis Wrote:
> 
>> No, you create *an array*, not objects of concrete type. Thus, no
>> constructor is called and an array contains a butch of uninitialized
>> class  references. And since no ctor is called, you can't pass any
>> ctor  parameters right there.
>> 
>> So you still need a loop to initialize the array properly.
>> 
> I see. so after i do the = new xyz[][](left,right), and i wanted to
> fill in x,y,z i'd have to
> 
> // this(x,y,z){} //still this constructor
> 
> z=100;
> for(int x=0; x<left; x++)
> for (int y=0; y<right; y++)
> xyz[x][y] = new xyz(x,y,z)

or the slightly nicer/neater version

z=100;
foreach(x, arr; xyz)
foreach (y, ref v in arr)
v = new xyz(x,y,z);

// I might have got x and y backwards


July 09, 2008
Era Scarecrow wrote:
 Now let me doublecheck once more. If i DID this.
> 
>  abc = new xyz[][](4,4);    //Non-stack and GC handles it, or i can malloc
>  abcd [4][4]xyz;    //(Stack / non-Stack) static allocation
> 
>  I'll assume that
>  1) abcd is an array of 4 pointers that have 4 pointers each
>  2) It is not created by the GC, but instead resides on the Stack? (Please confirm)

You probably meant this:

xyz[4][4] abcd;

abcd is contiguous space for 16 xyz values, accessed as a two-dimensional array.  I'm not sure what you mean when you talk about pointers, but unless xyz is a pointer type, there are not pointers involved.  Except that when passed to a function, static arrays are passed as the address of the first element.  This is all like in C.

And yes, it's allocated statically, or on the stack.  Unless you put it inside a struct, in which case you can allocate it in any way you like, as part of a struct instance.


Docs on heap allocating dynamic arrays can be a little tricky to find:
http://www.digitalmars.com/d/1.0/expression.html#NewExpression
July 10, 2008
On Thu, 10 Jul 2008 03:59:13 +0400, torhu <no@spam.invalid> wrote:

> Era Scarecrow wrote:
>   Now let me doublecheck once more. If i DID this.
>>   abc = new xyz[][](4,4);    //Non-stack and GC handles it, or i can malloc
>>  abcd [4][4]xyz;    //(Stack / non-Stack) static allocation
>>   I'll assume that
>>  1) abcd is an array of 4 pointers that have 4 pointers each
>>  2) It is not created by the GC, but instead resides on the Stack? (Please confirm)
>
> You probably meant this:
>
> xyz[4][4] abcd;
>

IIRC, both syntaxes are allowed, but "xyz[4][4] abcd;" is prefered.