Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Need some help with jagged array (2d array)

jagged array 2d array

  • Please log in to reply
7 replies to this topic

#1 orenduino

orenduino

    Member

  • Members
  • PipPip
  • 26 posts

Posted 29 March 2014 - 07:35 PM

Hi.

I am trying to make some kind of 2d array,

I have seen that the nearest thing to 2d array[,] is jagged array[][].

The jagged array is usually contain address (or pointer) to another arrays, its kind of index of arrays.

 

My code is very complicated, but I'll make it simple in order to present my problem.

(The actual code is much more complicated, but the idea is presented below)

int[] numbers1 = new int[5];
int[] numbers2 = new int[5];
int[] numbers3 = new int[5];
int[] temporary = new int[5];
..
.Some code to fill up all the arrays with numbers..
...
int [][] numbersArr = new int[3][];

tmporary = numbers1;
numberArr[0] = temporary;
tmporary = numbers2;
numberArr[1] = temporary;
tmporary = numbers3;
numberArr[2] = temporary;

.
some more code which involve changing the all the "numbers#" arrays

The result is  numberArr[0] numberArr[1] NumberArr[2] points to the same array, which is "temporary"

but what I need actually that it will have a copy of  "numbers" Arrays.(Which you'd get if you use 2d array)

I have tried to use "CopyTo" but I get the same result.

Any ideas ?

Thanks



#2 orenduino

orenduino

    Member

  • Members
  • PipPip
  • 26 posts

Posted 29 March 2014 - 07:41 PM

The actual code is getting data from COM1, and store it in 2d array, so I have mass of data, and the actual code is in a "while" loop, (about 64 loops)

But I always end with all 64 arrays  in numbersArr points to the same temporary COM buffer.



#3 jrlyman3

jrlyman3

    Advanced Member

  • Members
  • PipPipPip
  • 67 posts
  • LocationNorth St Paul. MN

Posted 30 March 2014 - 02:28 AM

I copied the example code and ran it (you obviously didn't since it has compile errors :) ) and it works fine.  I ran it both on the PC and the Netduino.  Here's the code I ran ... you must be doing something else.  Note that if you reuse the numbers1..3 arrays that will also change the values in the numbersArr.

        int[] numbers1 = { 101, 102, 103, 104, 105 };
        int[] numbers2 = { 201, 202, 203, 204, 205 };
        int[] numbers3 = { 301, 302, 303, 304, 305 };
        int[] temporary = { 401, 402, 403, 404, 405 };
        int [][] numbersArr = new int[3][];

        temporary = numbers1;
        numbersArr[0] = temporary;
        temporary = numbers2;
        numbersArr[1] = temporary;
        temporary = numbers3;
        numbersArr[2] = temporary;

        for (int i=0; i < 3; i++) {
            for (int j=0; j < 5; j++) {
                Debug.Print(numbersArr[i][j] + " ");
            }
            Debug.Print("\n");
        }


#4 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 30 March 2014 - 02:55 AM

orenduino--

P.S. You don't need to create temporary arrays unless you want to. You can also do this:
int [][] numbersArr = new int[3][];
numbersArr[0] = new int[] { 101, 102, 103, 104, 105 };
numbersArr[1] = new int[] { 201, 202, 203, 204, 205 };
numbersArr[2] = new int[] { 301, 302, 303, 304, 305 };
Chris

#5 orenduino

orenduino

    Member

  • Members
  • PipPip
  • 26 posts

Posted 30 March 2014 - 09:51 AM

Hi

ok, maybe I misslead you a little, here are the relevant parts of my codes.

the idea is to read data from the COM1 Buffer, and split it into groups of 4 bytes (or 32 bits).

public static byte[][] InBuff = new byte[64][];

  static void Netduino_COM1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            int BufferLength = Netduino_COM1.BytesToRead;
            int Xmax = 4;
            int Ymax = 64;
            
            byte[] buffer = new byte[BufferLength];
            byte[] XBuffer = new byte[Xmax];
            if (BufferLength >= 256)
            {
                Netduino_COM1.Read(buffer, 0, buffer.Length);

                for (Y = 0; Y < Ymax; Y++)
                {
                    for (X = 0; X < Xmax; X++)
                    {
                      XBuffer[X] = buffer[X + Y * 4];
                    }

                   // XBuffer.CopyTo(InBuff[Y], 0);
                    InBuff[Y] = XBuffer;
                    //Netduino_COM1.Write(InBuff[0], 0, InBuff[0].Length);
                   // XBuffer = InBuff[Y];
                   // Netduino_COM1.Write(XBuffer, 0, XBuffer.Length);
                }
                transmitSerialData();
            }
            //Netduino_COM1.Dispose();
            }

 static void transmitSerialData()
        {
            byte[] transmitArray = new byte[5];
            for (int i = 0; i < InBuff.Length; i++)
            {
                {
                    transmitArray = InBuff[i];
                    Netduino_COM1.Write(transmitArray, 0, transmitArray.Length);
                   // Netduino_COM1.Write(InBuff[0], 0, InBuff[0].Length);
                }
            }
        }

The data is being read correctly, and XBuffer contains the relevant data each cycle of the loop.

the problem is that InBuff[*] are all equal to the last value of XBuffer.



#6 jrlyman3

jrlyman3

    Advanced Member

  • Members
  • PipPipPip
  • 67 posts
  • LocationNorth St Paul. MN

Posted 31 March 2014 - 02:12 AM

OK, so here's the problem.  You load the data into XBuffer, then you store a pointer to that bffer into InBuff, you load the next set of data into XBuffer and store the same pointer into the next element of inBuff, and so on.  One way to fix it would be to move the new of XBuffer into the loop.  As in:

    for (Y = 0; Y < Ymax; Y++)
    {
        Xbuffer = new byte[Xmax];  
        for (X = 0; X < Xmax; X++)
        {
          XBuffer[X] = buffer[X + Y * 4];
        }
        InBuff[Y] = XBuffer;
    }

The down side of this is that this will use up twice the amount of memory.  If you use the data from the initial buffer it would save the memory.



#7 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 31 March 2014 - 07:05 AM

jrlyman3 is absolutely correct.

The pattern used by orenduino may be acceptable for a PC, but sucks a lot of RAM for a Netduino (and may run out of memory).

Some tips:

  1. prefer the old-plain-loop (in a dedicated Thread) over the event handler. If you use the serial for high data rate, the event could fire many times and -let's say- uselessly. Just leave a loop running for incoming data, then interleave each cycle with a brief pause (e.g. 10ms or more). Less elegant, but always under control.
  2. avoid, avoid, avoid re-instantiating (i.e. creating) brand new object on every call. The "buffer" and "XBuffer" arrays are created and destroyed on each event handling, and that's requires a lot of memory and an intensive garbage collection overhead. That is, you'll experience some "pauses" due the memory cleanup. Prefer a long-living instance (e.g. "InBuff"), and scratch your head with some tricky pattern in order to save precious ram.
  3. the Read method of the serial comes already with a copy-oriented signature: just specify the byte-array reference, then the offset and the actual length to be read. Simply store an integer for the offset, the data will be automatically placed in the buffer.

Finally, why do you use two separate array for receive and transmit? The same mechanism seen for RX can also be applied for TX...

Good luck!


Biggest fault of Netduino? It runs by electricity.

#8 orenduino

orenduino

    Member

  • Members
  • PipPip
  • 26 posts

Posted 01 April 2014 - 08:52 AM

Hi

 

Xbuffer = new byte[Xmax];

 

Did solve the problem, As I Suspect at first, it looks like that Jagged array is actually array of pointers to other arrays.

probably, Jagged array of "int" acts different comparing Jagged array of "bytes".

It was not obvious for me that arrays in microframework are not initialized when you create them (As in .net framework)..

 

 

 

prefer the old-plain-loop (in a dedicated Thread) over the event handler

as you see, I am waiting until all the DATA has sent completely, and then I read this data.

I took your wise advice, and initiate the Jagged Array on different loop, this make sure that it will instantiate only once per "powerup".

Since it is my first processor which supports multithread, I still think with single thread.

I was trained to use interrupts. events are the closest thing to interrupts in c# in this case.

I Will consider threats the next time. (Currently, its too much effort to migrate the code to multithreat)

 

Thanks






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.