Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Maybe what's happening is the `printf` function is interpreting the memory address of the `String` object as if it were a pointer to a char array. This leads to it printing seemingly random bytes (which are actually parts of the `String` object's internal data structure) instead of the string content you expect.


This sounds kinda plausible.

IIRC, some string implementations have separate implementations for very short strings vs. longer ones. Similar thing for vectors.

I also see some size-related logic in the (current?) String implementation [0] [1].

String is a class with no virtual methods, and its first data member is a pointer to the underlying buffer [2]. So if Stream.printf unintentionally type-puns String to char*, it might work out okay?

[0] https://github.com/arduino/ArduinoCore-API/blob/master/api/S...

[1] https://github.com/arduino/ArduinoCore-API/blob/master/api/S...

[2] https://github.com/arduino/ArduinoCore-API/blob/cb3ab4c90d71...


Although sizeof(String) > sizeof(char*), so any subsequent arguments to printf(...) would probably be screwed up.


Thanks, yeah, that seems to match this SO answer [0] which refers to some "small-string optimization" in the ESP32 libraries [1].

So basically the foot-gun is that smaller String()s appear to work "by accident".

[0] https://arduino.stackexchange.com/a/90332

[1] https://github.com/espressif/arduino-esp32/blob/7a82915de215...


It gets worse.

You're only printing 4 bytes because your string is sufficiently short, and the next byte it's reading is 0, since your capacity is small.

If your string were about 17 million bytes long (0x0101'0101 == 16843009 is the first value that causes problems), then your address, capacity, and size would all likely be nonzero, in which case your Arduino would just keep printing bytes until it lucked upon a zero, or overran its buffer so badly that it started trying to read different segments of memory and eventually segfaulted.


> your Arduino would just keep printing bytes until it lucked upon a zero, or overran its buffer so badly that it started trying to read different segments of memory and eventually segfaulted.

I don't think I've ever used an arduino core for something that had an MMU. It should happily keep printing all the way until the end of memory, and either stop there because it's zeros after, or wrap back to the start depending on the board. I have written code to dump out every byte in memory over serial before, just for kicks.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: