[Solved] Problem with passing variables by reference to a function

SO I have been experimenting with returning multiple values from a function, based on information I found in this thread at http://forum.arduino.cc/index.php?topic=48604.0 I wrote a small sketch to test out the method here:

boolean Fcn(int inval, int &outval)
{
outval=2*inval;
return (((inval/2)*2) == inval);
}

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
int progval[2];

Serial.println("Number = 1");
if( Fcn(1,progval[1]) ) {
  Serial.println("Number is even");
} else {
  Serial.println("Number is odd");
}
Serial.print("Output = ");
Serial.println(progval[1]);


Serial.println("Number = 4");
if(Fcn(4,progval[2])) {
  Serial.println("Number is even");
} else {
  Serial.println("Number is odd");
}
Serial.print("Output = ");
Serial.println(progval[2]);
}

void loop() {
while(true){}
}

It works as designed. The function returns “true” if the first parameter is even; “false” if it is odd. In “outval”, the function returns twice the “inval” value". So I decided to incorporate passing function parameters by reference in my actual code. The function “readln_ACode” is supposed to return four integers, read from a comma separated values file on an SD card. If I make the four variables global and define the function with no parameters - it works. However, if I define the parms local and pass them by reference, I get strange results. Zeroes for most of the integers and 25956 for one of them. (I mention the vaue, in case it triggers something). As I see it, it is a simple change which should work. I could use global parameters, but this needlessly uses extra variables and conplicates the code. The final storage for these integers is a set of four arrays. If anyone can see what I am doing wrong, I’d appreciate it. Been working on the problem for a couple of days. Here is the code:

/*
  SD card acode file read 
  Notes:
  function returns reference at http://forum.arduino.cc/index.php?topic=48604.0
 */
#include <SPI.h>
#include <SD.h>


File myFile;

boolean  readln_ACode(int &action, int &desc, int &option, int &stack) 
{
  String inputstring="";
  int inputvalues[4];
  byte inputchar;
  byte index=1;
  boolean Done=false;
  inputchar='\0';
  while ((! Done) && (myFile.available())) {
    inputchar=myFile.read();
    if (inputchar==',') {
    // comma found, have chars for number
      inputvalues[index]=inputstring.toInt();
      index ++;
      inputstring="";
    } else {
      if (inputchar == 13 ) {
        // EOL found; last number found
        Done = true;
        inputvalues[index]=inputstring.toInt();
      } else { 
        if (inputchar >= '0' && inputchar <='9') {
           // character is a digit; append to string
           inputstring=String(inputstring+String(char(inputchar)));
           inputstring="";
       } else {  
     }
    }
   }   
  }
  action  =inputvalues[1]; // all Global variables
  desc    =inputvalues[2];
  option  =inputvalues[3];
  stack   =inputvalues[4];
  return myFile.available();
}

void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("Initializing SD card...");

  pinMode(10, OUTPUT);

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  if (SD.exists("acode.txt")) {
    Serial.println("acode.txt exists.");
  }
  else {
    Serial.println("acode.txt doesn't exist.");
  }

  // open file 
  Serial.println("Opening acode.txt...");
  myFile = SD.open("acode.txt");
}

void loop()
{
  int saction;
  int sdesc;
  int soption;
  int sstack;
  boolean More=true;

  while (More) {
    More=readln_ACode(saction,sdesc,soption,sstack);
    if (More) {
      Serial.println(saction);
      Serial.println(sdesc);
      Serial.println(soption);
      Serial.println(sstack);
      Serial.println();
    }
  }
  while(true){}
}
  int inputvalues[4];
  action  =inputvalues[1]; // all Global variables
  desc    =inputvalues[2];
  option  =inputvalues[3];
  stack   =inputvalues[4];

A 4-element array has indexes 0, 1, 2, and 3; not 1, 2, 3, and 4.

What is happening here?

           inputstring=String(inputstring+String(char(inputchar)));
           inputstring="";

Looks like you carefully add the latest char to your inputstring and immediately throw the whole thing away.

djsfantasi: If anyone can see what I am doing wrong, I'd appreciate it.

Local variables in a function are only valid from - starting the function - until the function ends

So these local variables in your loop become invalid each time the loop is finished:

  int saction;
  int sdesc;
  int soption;
  int sstack;

Next time the loop begins, the value of these integers is "not defined" any longer. Maybe random numbers from re-used RAM sections.

If you want that local defined variables keep their contents from one function execution to the next function execution, you would have to declare them "static":

  static int saction;
  static int sdesc;
  static int soption;
  static int sstack;

Then those variable keep living and keep their contents, even when the function ends, just like "global" variables, but with a local scope of visibility.

jurs:
Local variables in a function are only valid from

  • starting the function
  • until the function ends

Understood, Jurs. This is the loop function, and I want and expect these variables to be local.

johnwasser:

A 4-element array has indexes 0, 1, 2, and 3; not 1, 2, 3, and 4.

Thank you for noticing, John. I had (wrongly) assumed that array[4] had the elements 0-4.

wildbill:
What is happening here?

           inputstring=String(inputstring+String(char(inputchar)));

inputstring="";




Looks like you carefully add the latest char to your inputstring and immediately throw the whole thing away.

Bingo! That line to “throw the whole thing away”, belonged in the else block above. After extracting the integer value, I wanted to clear the string. Great catch! I needed to follow my own advice when something inexplicably stops working - ask “what DIDN’T you change”! Ha ha. It was supposed to be a simple copy and paste. Helps when you paste it in at the correct line.