Simple array init question

Frits van Bommel fvbommel at REMwOVExCAPSs.nl
Mon Apr 9 13:34:37 PDT 2007


Dan wrote:
> Graham Wrote:
>> (And to be pedantic, int[5][5] is a 2D rectangular array, which in 
>> memory is exactly the same as int[25] - a 1D array, of course - so six 
>> of one and half a dozen of the other perhaps, but int[5][5] does have > 
>> 1 dimension :-))
> 
> Actually, you're wrong sir.  An int[5][5] produces an array containing 5 structs, each of:
> 
> struct Array {
>   size_t(or was it int?  uint?) length;
>   void* ptr;
> }
> 
> Each of those arrays then points to another array of 5 elements.

No, he was right. That struct is only used for dynamic arrays, not with 
static arrays. Static arrays are just a linear row of members stored 
in-place (but passed by reference).
You don't need to take my word for it, look at what the compilers do:
=====
$ cat test.d
import std.stdio;

int[5][5] matrix;

void main() {
     // Initialize
     foreach (r, inout row; matrix) {
         foreach (c, inout elt; row) {
             elt = r * 5 + c;
         }
     }

     // Access as a linear array:
     uint* p = cast(uint*) matrix.ptr;
         // (Note: ".ptr" is not actually stored but inserted as
         // a constant)
     for (size_t i = 0; i < 25; i++) {
         writef(p[i],' ');
     }
     writefln();
}
$ dmd -run test.d
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
$ gdc -o test test.d && ./test
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
=====

> What I believe you want is a rectangular array:
> 
> int[5,5], which will produce a single Array struct that you can access via taking a multiple of the first index added to the second index (or is it vice versa?)

Sorry, "int[5,5]" only compiles because of the obscure comma operator. 
The first 5 is evaluated and thrown away, what's left is a regular old 
int[5]. (Still stored in-place by the way)

> This notation tends to typically be inferior to int[25] for that very reason, each access requires math on two indices.  I might also note that it is typically more efficient to use a power of two for array sizes for indexing purposes - so long as the array size doesn't cause the OS you're working on to have difficulty allocating the space.

Providing two indices to a variable declared as "int[5,5]" will evaluate 
the first index and throw it away, only using the second. The comma 
operator strikes again.

> Some OS's allocate in 4kb units and then take 16 bytes for metadata, some allocate anything > 2kb in a "giant data" page-set which may be more inefficient than the smaller page-sets as it may allocate your data accross pages.



More information about the Digitalmars-d mailing list