Skip to content

Make String::move of an invalidated String result in an invalidated String #5127

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

Merged
merged 1 commit into from
Jul 18, 2016

Conversation

sandeepmistry
Copy link
Contributor

Currently the sketch below prints out:

b is false
s is true

However, I expect the output to be:

b is false
s is false

because the blah() function returns an invalidated String (NULL buffer, zero length). However, since the String s; is equivalent to String s(""), s's buffer is realloc(NULL, 0) resulting in a valid buffer.

String s;

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

  s = blah();

  if (s) {
    Serial.println("s is true");
  } else {
    Serial.println("s is false");
  }
}

String blah() {
  String b((const char*)NULL);

  if (b) {
    Serial.println("b is true");
  } else {
    Serial.println("b is false");
  }

  return b;
}

void loop() {
}

@@ -193,7 +193,7 @@ String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
void String::move(String &rhs)
{
if (buffer) {
if (capacity >= rhs.len) {
if (rhs && capacity >= rhs.len) {
strcpy(buffer, rhs.buffer);
len = rhs.len;
rhs.len = 0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder why this copy code is even here in the first place? Why not just always take over the buffer of rhs? That would be faster, and the only downside is that the buffer pointer for this string changes (but nobody should rely on it anyway)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@matthijskooijman good question!

Maybe it's to avoid memory fragmentation?

@PaulStoffregen @damellis @cmaglie do you have any thoughts on this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the only downside is that the buffer pointer for this string changes (but nobody should rely on it anyway)?

there is the c_str() operator and there are PR that pushes for using it outside the string class also for writing :-)

Maybe it's to avoid memory fragmentation?

I guess that's the reason, move is called from the c++11 move-constructor, so it's probably better to keep the original (rvalue) allocation whenever possible to avoid making "holes".

@cmaglie cmaglie merged commit f49c7ae into arduino:master Jul 18, 2016
@cmaglie cmaglie added this to the Release 1.6.10 milestone Jul 18, 2016
@sandeepmistry sandeepmistry deleted the invalidated-string-move branch July 18, 2016 17:57
fpistm added a commit to stm32duino/Arduino_Core_STM32 that referenced this pull request Feb 13, 2018
See arduino/Arduino#5127

Signed-off-by: Frederic.Pillon <[email protected]>
benwaffle pushed a commit to benwaffle/Arduino_Core_STM32 that referenced this pull request Apr 10, 2019
See arduino/Arduino#5127

Signed-off-by: Frederic.Pillon <[email protected]>
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

Successfully merging this pull request may close these issues.

4 participants