Personal computing discussed

Moderators: renee, SecretSquirrel, just brew it!

 
Crayon Shin Chan
Minister of Gerbil Affairs
Topic Author
Posts: 2313
Joined: Fri Sep 06, 2002 11:14 am
Location: Malaysia
Contact:

Arduino shell: two digit parameters don't get processed

Fri Feb 28, 2014 1:59 pm

I'm making a shell for my Arduino here. It's rather self explanatory:
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: FX-8350, 12GB DDR3, M5A99X EVO, MSI GTX 1070 Sea Hawk, Crucial MX500 500GB
Supply ship: [email protected], 12GB DDR3, M4A88TD-V EVO/USB3
Corsair: Thinkpad X230
 
morphine
TR Staff
Posts: 11600
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

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.

#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 :(
 
Crayon Shin Chan
Minister of Gerbil Affairs
Topic Author
Posts: 2313
Joined: Fri Sep 06, 2002 11:14 am
Location: Malaysia
Contact:

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

Fri Feb 28, 2014 5:02 pm

Wow, that worked! Thanks so much!
Mothership: FX-8350, 12GB DDR3, M5A99X EVO, MSI GTX 1070 Sea Hawk, Crucial MX500 500GB
Supply ship: [email protected], 12GB DDR3, M4A88TD-V EVO/USB3
Corsair: Thinkpad X230
 
morphine
TR Staff
Posts: 11600
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

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 :(
 
Crayon Shin Chan
Minister of Gerbil Affairs
Topic Author
Posts: 2313
Joined: Fri Sep 06, 2002 11:14 am
Location: Malaysia
Contact:

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

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: FX-8350, 12GB DDR3, M5A99X EVO, MSI GTX 1070 Sea Hawk, Crucial MX500 500GB
Supply ship: [email protected], 12GB DDR3, M4A88TD-V EVO/USB3
Corsair: Thinkpad X230
 
morphine
TR Staff
Posts: 11600
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

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 :(
 
Crayon Shin Chan
Minister of Gerbil Affairs
Topic Author
Posts: 2313
Joined: Fri Sep 06, 2002 11:14 am
Location: Malaysia
Contact:

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

Fri Feb 28, 2014 7:00 pm

I wouldn't have spotted that - you saved me hours of frustration! Thank you again!
Mothership: FX-8350, 12GB DDR3, M5A99X EVO, MSI GTX 1070 Sea Hawk, Crucial MX500 500GB
Supply ship: [email protected], 12GB DDR3, M4A88TD-V EVO/USB3
Corsair: Thinkpad X230
 
SecretSquirrel
Minister of Gerbil Affairs
Posts: 2726
Joined: Tue Jan 01, 2002 7:00 pm
Location: North DFW suburb...
Contact:

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

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
 
just brew it!
Administrator
Posts: 54500
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

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

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.
Nostalgia isn't what it used to be.

Who is online

Users browsing this forum: No registered users and 10 guests
GZIP: On