Arduino shell: two digit parameters don't get processed

From Visual Basic to GNU C, this is the place to talk programming.

Moderators: SecretSquirrel, just brew it!

Arduino shell: two digit parameters don't get processed

Postposted on Fri Feb 28, 2014 1:59 pm

I'm making a shell for my Arduino here. It's rather self explanatory:
Code: Select all
void shell() {
  Serial.println(inputstring);
  String *inputstring_processed;
  inputstring_processed=splitcmd(inputstring, ' ');
  if (inputstring_processed[0] == "adctest") {
    adc_test();
  }
  if (inputstring_processed[0] == "dactalk") {
    int param1, param2;
    String tempstring1, tempstring2;
    char cstring1[100], cstring2[100];
    tempstring1=inputstring_processed[1];
    tempstring2=inputstring_processed[2];
    tempstring1.toCharArray(cstring1,100);
    tempstring2.toCharArray(cstring2,100);
    param1 = atoi(cstring1);
    param2 = atoi(cstring2);
    dac_talk(param1,param2);
  }
  else {
    Serial.println("Available commands: adctest dactalk");
  }
  Serial.print("auteur> ");
}
String* splitcmd(String command, char delimiter){
  int endposition=-1;
  int startposition=0;
  int index=0;
  String cli[10];
 
  do{
    endposition = command.indexOf(delimiter,endposition+1);
    cli[index]=command.substring(startposition, endposition);
    index++;
    startposition=endposition;
  }
  while(endposition!=-1);

  Serial.print ("cli[0]: ");  Serial.println(cli[0]);
  Serial.print ("cli[1]: ");  Serial.println(cli[1]);
  Serial.print ("cli[2]: ");  Serial.println(cli[2]);
  Serial.print ("cli[3]: ");  Serial.println(cli[3]);
  return cli;
}


And it works, but when I put two digit numbers as parameters, suddenly inputstring_processed[0] doesn't equal "dactalk" any more! It doesn't make sense.

auteur is listening: dactalk 1 23
cli[0]: dactalk
cli[1]: 1
cli[2]: 23
cli[3]:
Available commands: adctest dactalk
auteur> dactalk 1 3
cli[0]: dactalk
cli[1]: 1
cli[2]: 3
cli[3]:
wrote this to DAC: 1 11
auteur> dactalk 1 9
cli[0]: dactalk
cli[1]: 1
cli[2]: 9
cli[3]:
wrote this to DAC: 1 1001
auteur> dactalk 1 0
cli[0]: dactalk
cli[1]: 1
cli[2]: 0
cli[3]:
wrote this to DAC: 1 0
auteur> dactalk 1 10
cli[0]: dactalk
cli[1]: 1
cli[2]: 10
cli[3]:
Available commands: adctest dactalk
auteur> dactalk 12 3
cli[0]: dactalk
cli[1]: 12
cli[2]: 3
cli[3]:
Available commands: adctest dactalk
auteur>
Mothership: Thuban 1055T@3.7GHz, 12GB DDR3, M5A99X EVO, GTX470+Icy Vision Rev.2@840/3800, Vertex 2E 60GB
Supply ship: Sargas@2.8GHz, 12GB DDR3, M4A88TD-V EVO/USB3
Corsair: Macbook Air Ivy Bridge
Crayon Shin Chan
Minister of Gerbil Affairs
 
Posts: 2236
Joined: Fri Sep 06, 2002 11:14 am
Location: Malaysia

Re: Arduino shell: two digit parameters don't get processed

Postposted on Fri Feb 28, 2014 3:48 pm

My C++ is very rusty, so I'm probably talking crap. With that disclaimer...

I think that you have a mess there because you're not passing the set of strings back/forth cleanly. "return cli" at the end of splitcmd() will return a reference to a variable that's local to the function. When you call splitcmd(), you may get something back, or you may get garbage.

If you go http://www.compileonline.com/compile_cpp11_online.php and run this code I made, you'll see that it works out horribly.

Code: Select all
#include <iostream>

using namespace std;


string *splitcmd() {
   
    string test[3];
   
    test[0]= "dactalk";
    test[1]= "1";
    test[2]= "2";
   
    return test;
}

int main() {
    string *result= splitcmd();
   
    cout << result[0];
    cout << result[1];
    cout << result[2];
   
   return 0;
}
There is a fixed amount of intelligence on the planet, and the population keeps growing :(
morphine
Gerbil Khan
Silver subscriber
 
 
Posts: 9934
Joined: Fri Dec 27, 2002 8:51 pm
Location: Portugal (that's next to Spain)

Re: Arduino shell: two digit parameters don't get processed

Postposted on Fri Feb 28, 2014 5:02 pm

Wow, that worked! Thanks so much!
Mothership: Thuban 1055T@3.7GHz, 12GB DDR3, M5A99X EVO, GTX470+Icy Vision Rev.2@840/3800, Vertex 2E 60GB
Supply ship: Sargas@2.8GHz, 12GB DDR3, M4A88TD-V EVO/USB3
Corsair: Macbook Air Ivy Bridge
Crayon Shin Chan
Minister of Gerbil Affairs
 
Posts: 2236
Joined: Fri Sep 06, 2002 11:14 am
Location: Malaysia

Re: Arduino shell: two digit parameters don't get processed

Postposted on Fri Feb 28, 2014 6:30 pm

What worked? What'd you change?
There is a fixed amount of intelligence on the planet, and the population keeps growing :(
morphine
Gerbil Khan
Silver subscriber
 
 
Posts: 9934
Joined: Fri Dec 27, 2002 8:51 pm
Location: Portugal (that's next to Spain)

Re: Arduino shell: two digit parameters don't get processed

Postposted on Fri Feb 28, 2014 6:38 pm

That was exactly the problem - so I declared the String array elsewhere, and it works perfectly now!
Mothership: Thuban 1055T@3.7GHz, 12GB DDR3, M5A99X EVO, GTX470+Icy Vision Rev.2@840/3800, Vertex 2E 60GB
Supply ship: Sargas@2.8GHz, 12GB DDR3, M4A88TD-V EVO/USB3
Corsair: Macbook Air Ivy Bridge
Crayon Shin Chan
Minister of Gerbil Affairs
 
Posts: 2236
Joined: Fri Sep 06, 2002 11:14 am
Location: Malaysia

Re: Arduino shell: two digit parameters don't get processed

Postposted on Fri Feb 28, 2014 6:41 pm

Heh glad it worked. It's been almost 15 years since I last touched C++, so I'm glad I still knew something :lol: . I'll admit it took me the better part of half an hour to spot something that should be obvious to anyone that actually knows their way around the language though.
There is a fixed amount of intelligence on the planet, and the population keeps growing :(
morphine
Gerbil Khan
Silver subscriber
 
 
Posts: 9934
Joined: Fri Dec 27, 2002 8:51 pm
Location: Portugal (that's next to Spain)

Re: Arduino shell: two digit parameters don't get processed

Postposted on Fri Feb 28, 2014 7:00 pm

I wouldn't have spotted that - you saved me hours of frustration! Thank you again!
Mothership: Thuban 1055T@3.7GHz, 12GB DDR3, M5A99X EVO, GTX470+Icy Vision Rev.2@840/3800, Vertex 2E 60GB
Supply ship: Sargas@2.8GHz, 12GB DDR3, M4A88TD-V EVO/USB3
Corsair: Macbook Air Ivy Bridge
Crayon Shin Chan
Minister of Gerbil Affairs
 
Posts: 2236
Joined: Fri Sep 06, 2002 11:14 am
Location: Malaysia

Re: Arduino shell: two digit parameters don't get processed

Postposted on Sat Mar 01, 2014 12:14 am

Never return a pointer or reference to a locally scoped, automatically allocated variable in C++ (or really C either, for that matter). It goes out of scope the moment the function returns and will be deallocated. That also goes for class internals like string.data(). If you need to return a pointer, you need to declare the pointer, then explicitly instanciate the object with a new(). Of course then you need to remeber to to delete() it later.

--SS
SecretSquirrel
Gerbil Jedi
Gold subscriber
 
 
Posts: 1686
Joined: Tue Jan 01, 2002 7:00 pm
Location: The Colony, TX (Dallas suburb)

Re: Arduino shell: two digit parameters don't get processed

Postposted on Sat Mar 01, 2014 11:23 am

Yeah, returning values in C/C++ can easily cause problems like this since there's no automatic reference counting or garbage collection.

The general rule of thumb is: If you want to return a pointer or reference to something from a function, the "something" cannot be a locally declared variable unless it is static.

Passing in a pointer or reference to the structure you want filled in would be the normal way to handle this. Alternatively you can return a pointer to something that has been allocated from the heap (with the "new" operator), but then the caller is implicitly responsible for deleting it when it doesn't need it any more (otherwise you will have a memory leak). You could also safely return it by wrapping it in a class/struct and returning it by value, but that would be inefficient since you're forcing the compiler to generate code to implicitly make a copy of the entire array.
(this space intentionally left blank)
just brew it!
Administrator
Gold subscriber
 
 
Posts: 37512
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer


Return to Developer's Den

Who is online

Users browsing this forum: No registered users and 1 guest