Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Concat operator + with random() value leads to crash #143

Closed
sebromero opened this issue Mar 11, 2021 · 3 comments
Closed

Concat operator + with random() value leads to crash #143

sebromero opened this issue Mar 11, 2021 · 3 comments

Comments

@sebromero
Copy link

I found that when I concatenate a string directly (without wrapping it in a String object) with a number obtained from random() I get strange results.
When random() is used with a parameter, the resulting string contains garbage obtained from memory where it probably shouldn't read from.
When using random() without parameter the program crashes. On Portenta I get the red S.O.S flash, on the MKR1000 for example it just stops responding. I started to investigate but haven't found the culprit yet. It crashes somewhere in concat() when reading the string length using strlen().

void setup() {  
  Serial.begin(9600);
  while(!Serial);  

  //String newMessage = "Hello World " + random(1024); // Prints garbage:�����������3�������m���c���⸮�������Envie M7
  String newMessage = "Hello World " + random(); // Crashes
  //String newMessage = "Hello World " + String(random()); // Works
  //String newMessage = "Hello World " + String(random(1024)); // Works
  
  Serial.println(newMessage);
}
  
void loop() {}
@sebromero
Copy link
Author

Maybe something for you @per1234 ? :-)

@matthijskooijman
Copy link
Collaborator

I believe what happens here is that "Hello world" resolves to a const char* to the first character of the string, and the + random() just adds an offset to this pointer. If that offset is more than the string length, you will end up pointing to random memory, which might look like a very long string if there is no NUL byte in memory anywhere near. It might even end up pointing to an invalid address, which can lead to a hardfault on ARM processors, which I suspect is what you're seeing.

You could probably try:

String newMessage = "Hello World " + 2;

and this would print llo World, or:

String newMessage = "Hello World " + 0xffffff;

(or some other similarly big number which goes beyond the end of RAM) and this will also crash.

I'm inclined to close this as not a bug, since this is expected behavior (C-style strings do not support concatenation with +) and even though it's somewhat confusing, I don't think really think there is any way we could handle this particular code in a better way (maybe the compiler could generate a warning in the constant case, but probably not when adding e.g. random()).

@sebromero
Copy link
Author

@matthijskooijman What you're saying makes total sense! Thanks for sharing that. There is indeed an assignment operator String & operator = (const char *cstr); for char pointers. Hmm, yes, you're right, it's expected behaviour in that sense. Quite a bit of a trap for beginners. Well, it even got me ;-) I can't think of a way to avoid this problem currently. Let's close this and hopefully someone who comes across this issue finds the explanation here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants