Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 10 of 10

Thread: Class String bug: c_str() method return a null pointer

  1. #1
    Junior Member
    Join Date
    Oct 2020
    Posts
    3

    Class String bug: c_str() method return a null pointer

    Hello. I am a new member on this forum. I have been consulting it for a long time with great interest. Yesterday I found what I think is a bug with the Class String.

    After creating a String initialized with an empty c string ( String * str = new String (""); ), the c_str () method returns a null pointer with my Teensy. I rather expect a valid pointer to an empty c string.

    However if the initialization is done with a non-empty c string and then I reassign an empty c string after, c_str() returns a valid pointer to an empty c string.

    The bug seems to have been introduced in the copy method in WString.cpp:

    Code:
    String & String::copy(const char *cstr, unsigned int length)
    {
    	if (length == 0) {
    		if (buffer) buffer[0] = 0;
    		len = 0;
    		return *this;
    	}
    	if (!reserve(length)) {
    		if (buffer) {
    			free(buffer);
    			buffer = NULL;
    		}
    		len = capacity = 0;
    		return *this;
    	}
    	len = length;
    	strcpy(buffer, cstr);
    	return *this;
    }
    With the addition of the condition if (length == 0) the buffer is never allocated with initialization of an empty c string.
    I imagine the goal here was to avoid allocating a buffer if the String is empty. This is good for optimization but it introduced the bug for c_str().

    To avoid this I propose to modify c_str() in WString.h so as to force the method to return a pointer to an dummy empty static c string if the buffer has never been allocated.
    Like this:

    static char dummy = 0;
    const char * c_str() const {return (buffer == NULL) ? &dummy : buffer; }

    With this simple modification in a future version the optimization remains and c_str() guarantees never return a null pointer.

  2. #2
    Junior Member
    Join Date
    Oct 2020
    Posts
    8
    It's just a bit older copy of Arduino's WString. Solution could be simply make an upgrade of code base to be up to date with current Arduino code base.

    In the latest Arduino core it seems to be much harder to create instance, that returns nullptr from c_str().

    However I can imagine for example
    Code:
    char * ptr = nullptr; String str { ptr };
    which results into nullprt returned by c_str() (in latest Arduino codebase). However it's not so easy to archieve it, as you can't just pass the nullptr without explicit cast to char* due to ambiguity. The empty string in current teensy code base is way easier.

  3. #3
    Junior Member
    Join Date
    Oct 2020
    Posts
    3
    Thanks for your reply KIIV.

    My solution for the moment is quite simple. I never use the c_str () method of the Class String directly. Instead, I call a global function that I created that checks if c_str () returns a null pointer and if so it replaces it with a valid pointer to a null character.

    Code:
    const char    *c_str(const String &Str)
    {
      static const char dummy = 0;
      const char  *cstr = Str.c_str();
    
      return !cstr ? &dummy : cstr;
    }
    
    Example:
    char * ptr = nullptr; String str { ptr };
    
    char *cstr = c_str(str); // The global c_str() function return valid pointer to static dummy variable.

  4. #4
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    7,096
    I agree, this is a bug and should be fixed.
    Don't you want to create a Pullrequest @ github to fix this?

    Otherwise i can take a look.

  5. #5

  6. #6
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,069
    And welcome back Frank!!

  7. #7
    Junior Member
    Join Date
    Oct 2020
    Posts
    8
    In theory it could've been fixed in teensy and teensy3 core too

    Maybe little sync with Arduino core wouldn't hurt (where is much less likely to return nullptr from c_str). Btw: they even fixed possible deadlock with HardwareSerial.print inside of ISR (for AVRs) many years ago.

  8. #8
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,069
    Quote Originally Posted by KIIV View Post
    In theory it could've been fixed in teensy and teensy3 core too
    Fixed on Teensy 3.x too.

    https://github.com/PaulStoffregen/co...444313bd95b8cd


    Maybe little sync with Arduino core wouldn't hurt (where is much less likely to return nullptr from c_str).
    Their code has changed quite a lot. Their invalidate() function does set the pointer to NULL.

    For now, I'm going to leave things as they are and address incompatibilities as they arise.


    Btw: they even fixed possible deadlock with HardwareSerial.print inside of ISR (for AVRs) many years ago.
    Like so many issues, I will only work on this when someone reports it with a test case. If you want me to dig into this, please start a new thread with code to reproduce the problem.

  9. #9
    Junior Member
    Join Date
    Oct 2020
    Posts
    3
    Thank you guys.

  10. #10
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    7,096
    Quote Originally Posted by PaulStoffregen View Post
    And welcome back Frank!!
    Thank you.

    Trying to get up to date here.

    I made a short trip into the Arduino-ESP32 world.
    The progress there is impressive.
    For communication things it is (now) a well supported platform, the documentation has become good and for everything you can find stable libraries.
    But uploading is still a pain (slow), compiling takes ages - especially if you use web servers and clients, spiffs, nvs and more. But everything you need is there.

    The Teensy platform is still more fun. Even if some things are more complicated or missing.
    For the ESP I liked rtos (we NEED that), and the preferences lib.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •