Output and array

I'm trying to temporarily save two values into an array. One value is a latitude (from my GPS), and another one that I made up. So far, I am able to load the latitude value into the array with no problem, but when I try to load the second value (it is commented out in the code below), the output that I get goes haywire (i.e.: I start to get all sort of weird characters zooming by the serial monitor screen).

Could I have missed something in the syntax?

#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(3, 2);
Adafruit_GPS GPS(&mySerial);
#define GPSECHO  false
boolean usingInterrupt = false;
void useInterrupt(boolean); // Func prototype keeps Arduino 0023 happy

int counter = 0;      // set the counter to zero
char* products[][2]= { };

void setup()  
{
  Serial.begin(9600);
  Serial.println("Adafruit GPS library basic test!");

  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);   // 1 Hz update rate
  GPS.sendCommand(PGCMD_ANTENNA);
  useInterrupt(true);
  delay(1000);
  mySerial.println(PMTK_Q_RELEASE);
}


SIGNAL(TIMER0_COMPA_vect) {
  char c = GPS.read();

#ifdef UDR0
  if (GPSECHO)
    if (c) UDR0 = c;  
#endif
}

void useInterrupt(boolean v) {
  if (v) {
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
    usingInterrupt = true;
  } else {
    // do not call the interrupt function COMPA anymore
    TIMSK0 &= ~_BV(OCIE0A);
    usingInterrupt = false;
  }
}

uint32_t timer = millis();

void loop()                     // run over and over again
{
  if (! usingInterrupt) {
    // read data from the GPS in the 'main loop'
    char c = GPS.read();
    // if you want to debug, this is a good time to do it!
    if (GPSECHO)
      if (c) Serial.print(c);
  }
  
  // if a sentence is received, we can check the checksum, parse it...
  if (GPS.newNMEAreceived()) {
    if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
      return;  // we can fail to parse a sentence in which case we should just wait for another
  }

  // if millis() or timer wraps around, we'll just reset it
  if (timer > millis())  timer = millis();

  // approximately every 2 seconds or so, print out the current stats
  if (millis() - timer > 2000) { 
    timer = millis(); // reset the timer

    // Print GPS info    
    if (GPS.fix) {

      ////Set counter
      counter = counter + 1;  // Then, start the line counter
      Serial.print(counter);        
      Serial.print(" ");
                      
      //////////// Print the Latitude & speed
      Serial.print(GPS.latitude, 5);     //Lat number
      Serial.print(" ");
      Serial.print(GPS.longitude, 5);    //Lon number
      Serial.println(" ");         
              
                    
                    // Creating the array of subset data
                    if (counter == 5) {
                      Serial.println();
                      Serial.print("Line number ");
                      Serial.print(counter);
                      Serial.println(" will go into the array");                                    

             
                      //Load the latitude into an array  (example lat value:  1118.33544)
                      char lat1[12];    //This will account for potential "negative" latitutdes
                      dtostrf(GPS.latitude, 6, 5, lat1);    //convert float to string
                      strncat (lat1, '\0', 12);       // add a NULL terminator at the end of the variable "lat1" (just in case)           
                      strcpy(products[0][0], lat1);    //add "lat1" value to the "products" array in position [0][0]
                      
                     
                      //Now, let's try loading a second element into the array
                      //strcpy(products[0][1], "5555.55555");                      


                      //Lets print what I have in my array
                      Serial.println("Below is what I have in my array:");                      
                      char array1[50] = {};
                      snprintf(array1, sizeof(array1), "%s %s", products[0][0], products[0][1]);  
                      Serial.println(array1);
                      Serial.println();             
                      
                    }
                    
    }
  }
}
char* products[][2]= { };

When you don't supply a value in the square brackets, the compiler counts the initializers to determine the array size.

An array size of 0 is pretty much useless.

                      strcpy(products[0][0], lat1);    //add "lat1" value to the "products" array in position [0][0]

You have now overflowed the array AND products[0][]0] does not point to any space, so you just shit on memory you don't own.

                  //strcpy(products[0][1], "5555.55555");

And, here, you're trying to make it even worse.

Paul... of course! Thanks for the pointer... I can't believe I overlooked this. I changed the matrix definition to reflect a 1x2 matrix, got rid of the strcpy commands, and all is happy now.

Thanks!

Ok... I'm still playing around with arrays in arduino but I am having a bit of trouble understanding how to work with them. After some fumbling, I was able to load some basic lat & lon values into an array called "products". Now, I've been trying to copy the contents of the "products" array on to another called "arrayout0", but so far I haven't had any luck.

I thought memcpy would do the trick, but I'm haven't been able to make it work yet. Does anyone have any suggestions on what I could try/doing wrong? Thanks!

As global variables I have:

char *products[1][2];
char *arrayout0[1][2];

                 // Creating the array of subset data
                    if (counter == 3) {
                      Serial.println();

                      //Load the latitude into an array  (example lat value:  1118.33544)
                      char lat1[12];    //This will account for potential "negative" latitutdes
                      dtostrf(GPS.latitude, 4, 5, lat1);    //convert float to string
                      products[0][0] = lat1;
                      
                      char lon1[13];    //This will account for potential "negative" latitutdes
                      dtostrf(GPS.longitude, 5, 5, lon1);    //convert float to string
                      products[0][1] = lon1;
                      
                      Serial.println("In memory I have: ");
                      Serial.println(products[0][0]);
                      Serial.println(products[0][1]);   

                      //Now, copy the contents of "products" array to "arrayout0"
                      memcpy(arrayout0, products, sizeof(products));
                
                    } else if (counter == 5) {      
                      Serial.println("Now, in memory I have:");
                      Serial.println(arrayout0[0][0]);    // this should be the contents of products[0][0]
                      Serial.println(arrayout0[0][1]);    // this should be the contents of products[0][1]                
              }

As global variables I have:

char *products[1][2];
char *arrayout0[1][2];

Arrays of dimension 1 are pretty much useless. Are these eventually going to get larger?

An array like so:

int spaceReserved[4][5];

reserves space for 20 ints.

An array like:

int *noSpaceReserved[4][5];

reserves space for 20 pointers to int but does NOT reserve space for the ints that are to be pointed to and does not define where the pointers point to.

Your arrays reserve space for the pointers, but do not make the pointers point anywhere and do not reserve space for the data to be pointed to.

                      products[0][0] = lat1;

So, this pointer now points to lat1, which is allocated on the stack.

                      products[0][1] = lon1;

This pointer now points to lon1, which is allocated on the stack.

                      memcpy(arrayout0, products, sizeof(products));

The 2 pointers are now copied, so you have 4 pointers to space on the stack.

When that function ends, you have 4 pointers to space that will be overwritten without notice. How useful is that?

While there is a close relationship between pointer and arrays, you problems have nothing to do with arrays and everything to do with not understanding pointers.

Oh, and "it doesn't work" is pretty lame. You have not explained what that code actually does, or how that is different from what you want. Of course some of that is obvious, and some of the problems (like not understanding pointers) is obvious. How to fix the problem though isn't, since it isn't Storing lat and lon as strings doesn't make sense, since the string representation can be created at any time, and takes more space than the long or float value.

If you MUST store them as strings, you need to define a 3D array of chars, not a 2D array of pointers.

I see... I will try storing them as a float to see how that works.