www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Help with multi-dimentional array

reply Era Scarecrow <rtcvb32 yahoo.com> writes:
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
Jul 09 2008
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"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. :)
Jul 09 2008
next sibling parent reply Era Scarecrow <rtcvb32 yahoo.com> writes:
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
Jul 09 2008
parent reply Era Scarecrow <rtcvb32 yahoo.com> writes:
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
Jul 09 2008
next sibling parent BCS <ao pathlink.com> writes:
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.
 

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
Jul 09 2008
prev sibling parent torhu <no spam.invalid> writes:
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
Jul 09 2008
prev sibling next sibling parent "Koroskin Denis" <2korden+dmd gmail.com> writes:
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.
Jul 09 2008
prev sibling parent "Koroskin Denis" <2korden gmail.com> writes:
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.
Jul 10 2008