May 02, 2024, 04:47:15 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Passing an array?

Started by lviklund, February 24, 2006, 11:09:26 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Ionic Wind Support Team

It only appeared to work because your printing the result right after you were setting it.  Trying to access a dynamic array the 'c' way won't work in Aurora as ilustrated by this little test code:


double *pa;
global sub main()
{
pa = new(double,10*10);
*pa[0][1]=10;
writeln(NumToStr(*pa[1][0]) + "\n");
while (GetKey() = "") ;

}


When you used the syntax [][] the compiler allowed it because of a recent change in precendence rules to solve a problem with pointer arrays.  What it does is just multiply each index by the type size and add it to the memory address without reguard to dimension so "[1][0]" accesses the same memory location as "
  • [1]"

    Array offsets are calculated by the compiler because it knows the size of the data and the dimension of the array.  When you allocate memory there are no dimenstions, only a raw block of memory so you need to do the calculations yourself.

    For example:
    int a[15,15];
    a[5,10] = 100;

    The compiler knows the dimensions of the array from the first statement so it can calculate the proper location in the array:

    a[5,10]
    is calculated as:
    &a + ((5*1) + (10*15))*len(int);

    In general, depending on whether you want row or column order, the calcualtions for offsets are as such: (n=index, dim=dimension)

    2 dim array = (n1 * dim0 + n0)*datasize;
    3 dim array = ((n2 * dim0 * dim1) + (n1 * dim0) + n0) * datasize;
    4 dim array = ((n3 * dim0 * dim1 * dim2) + (n2 * dim0 * dim1) + (n1 * dim0) + n0) * datasize;

    The final dimension in an array is only used for out of bounds checking in some languages.  Usually interpreters.

    Dynamic arrays only support one dimension unless you use a bit of pointer math and the above formulas.  This change to your code verifies the writes with a second set of loops....


    global sub main()
    {
      int num = 3;

      double *pMatrix;

      pMatrix = new( double, num*num*num*num );

      if ( pMatrix = null )
       {
         writeln("insufficient memory\n");
       }
      else
       {
    //write the data
        for(int i = 0; i <= num-1; i++)
          {
          for(int j = 0; j <= num-1; j++)
            {
            for(int k = 0; k <= num-1; k++)
              {
              for(int l = 0; l <= num-1; l++)
                {
                *(double)(pMatrix+(l+(k*num)+(j*num*num)+(i*num*num*num))*8)  = (1+i)*1000+(1+j)*100+10*(k+1)+l+1;
                }
              }
            }
          }
    //verify the data
        for(i = 0; i <= num-1; i++)
          {
          for(j = 0; j <= num-1; j++)
            {
            for(k = 0; k <= num-1; k++)
              {
              for(l = 0; l <= num-1; l++)
                {
                writeln( numtostr( *(double)(pMatrix+(l+(k*num)+(j*num*num)+(i*num*num*num))*8) ) + "    " );
                }
              writeln( "\n" );
              }
            writeln( "\n" );
            }
          writeln( "\n\n" );
          }
        delete pMatrix;
       }
      while (GetKey() = "");

      return;
    }
Ionic Wind Support Team

lviklund

Goosh!!

My q stirred up some interesting thoughts here.
Good reading.

Thank you all for the discussion.

I have to ask my q again from a different angle.

If I have an Array of strings and I would like to pass the whole array as an argument to a external function, is that possible?

How?

something like:

func(array[])

that sends some kind of adress for the whole array to the external function.

I don't get this.
Lost! Que, Uh.... ???

Does it make any sense?

Earn

And the answer is......ÂÃ, Ã‚Ã,  ??? uh, errrr, what's the question again?
.
.
.
Oh yeah!ÂÃ,  Right from the manual, "A string array allocated by NEW has to be accessed using two indices."ÂÃ,  :)
declare printstring(pArray as pointer, cnt as int);

global sub main ()
{
ÂÃ,  ÂÃ, int num = 4;ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  // a variable that compiler does not know the value
ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  // of at compile time, only at runtime is it known

ÂÃ,  ÂÃ, string *foo = new ( string, num);

ÂÃ,  ÂÃ, if ( foo = NULL )ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ, // check if foo fails to be allocated
ÂÃ,  ÂÃ,  ÂÃ, {
ÂÃ,  ÂÃ,  ÂÃ,  writeln ("there is insufficient memory for foo");
ÂÃ,  ÂÃ,  ÂÃ, }
ÂÃ,  ÂÃ, else
ÂÃ,  ÂÃ,  ÂÃ, {
*foo[0,0] = "This ";
*foo[1,0] = "is ";
*foo[2,0] = "a ";
*foo[3,0] = "test ";
ÂÃ,  ÂÃ,  ÂÃ, }
printarray(foo, num);
delete foo;ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ, // always free up the memory used with new
while (GetKey() = "");

ÂÃ,  return;
}

sub printarray(pArray as pointer, cnt as int)
{
for ( int n = 0; n < cnt; n++ )
{
writeln(*(string)pArray[n,0] + "\n" ); // show foo's values
}
}





Parker

Because a string is actually an array of 255 bytes. But you have to be careful when using an array of strings, since overwriting one won't cause an error but it will bring unexpected results.

Ionic Wind Support Team

See the heapsort.src example.
Ionic Wind Support Team

John S

lviklund,
It has stimulated quite a bit of thought. 
I think to pass the address of array[] you write:

func( array )    // array is a pointer to the first element in array[]

but inorder to make sure func () knows how big array[] is use:

func( array, N )   // array is a pointer to the first element in array[]
                        // N is the mumber of elements in array[]


btw,   I have to double check my coding, but I got 1 byte for:

       writeln ("\n" +  numtostr( len( string ) ) + " bytes\n");       //  prints '1 bytes' to the screen not '255 bytes'

I could be due to type casting in numtostr().
John Siino, Advanced Engineering Services and Software

Ionic Wind Support Team

LEN(string) returns 1 since a string is an array of bytes.

I will have to think about hard coding 255 into the LEN function.
Ionic Wind Support Team

Parker

I think LEN(STRING) should return 255, and BASELEN(STRING) should return 1.

LarryMc

I know, stupid question:

How do I find the length of a string variable that contains "Duh".  I'm expecting an answer of 3.
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Ionic Wind Support Team

len(variable);

What we were discussing was the compiler returning the length of a variable type.  LEN works on variables, intrinsic type names such as STRING, FLOAT, DOUBLE, and on Structure names.

print(len(DOUBLE));  returns 8 for example

a = "Duh";

print(len(a)); returns 3
Ionic Wind Support Team

LarryMc

Like I said,"stupid question".  And that's a big 3 on the 'duh'. ;D
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

John S

John Siino, Advanced Engineering Services and Software

LarryMc

That'll work.

Some days it just don't pay for me to come out from under the porch! ;D
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

lviklund

Here is another Duh.....

I have just realized that I did understand how to pass string arrays.
The problem is that the function that is receiving expects a Fieldarray :o ??? :P.
Never heard of!

I will try to figure out what that is tonight.

Lasse