very strange and erratic behaviour of dtostrf

While building a program I ran in to some (to me) very strange behaviour.

I use dtostrf to convert floats to chars with a set precision. This seems to work. In a certain function I would use this to format 2 numbers before out putting them to a screen or serial.

At some point I found that changing a bit of seemingly unrelated code, would mess up the value of the first converted variable.

I’ve cut away redundant code and slimmed it down to the code at the bottom.

The expected serial output is an endless supply of:

123.4
678.9

123.4
678.9

The thing that is baffling me that if I do not call the foo or the bar function, or change the parameter of the foo function from String str to char str[4], then suddenly my output changes to:

9
678.9

9
678.9

Is there anybody that can explain what is happening?

int param1 = 0;

void setup()   {
  Serial.begin(115200);
}

void foo(String str){
  str = "";
}

void bar(){
  param1 = 0;
} 

void loop() {

  if(param1 == 2){
    bar();
    foo( "" );
  }

  char strVal1[4];
  char strVal2[4];
  dtostrf(123.45, 3, 1, strVal1);
  dtostrf(678.90, 3, 1, strVal2);
  Serial.println(strVal1);
  Serial.println(strVal2);
  Serial.println("------");

  delay(500);

}

How many elements in the array are needed to hold 123.45 to one decimal place?

  1. 1
  2. 2
  3. 3
  4. .
  5. 5
  6. the terminating NULL

How big is the array you provided?

  char strVal1[4];

What happens when you crap on memory outside the bounds of your array? Who knows? Hell, you might have even been responsible for Trump being elected president.

Wow... really...?!

There is no safety mechanism preventing me from overloading a char and having Trump become president???

Wow...

I'll test ASAP and let you know if this solves everything.

Any chance that if I let this program run for a while I can get Trump impeached?

There is no safety mechanism preventing me from overloading a char and having Trump become president???

How can there be? dtostrf() gets a pointer to the array. It has no idea how big the array is. It assumes, wrongly in this case, that the called provided a pointer to an array that was big enough.

That dtostrf() tried to park a 37 foot motor home in a compact spot, and wiped out a kiosk, two other cars, and 4 pedestrians, is not dtostrf()'s fault. It is the fault of the person who told dtostrf() to park in that spot.

Any chance that if I let this program run for a while I can get Trump impeached?

I think you need to write beyond the bounds of some other array to make that happen.

Hey PaulS,

I just tried working with a larger char array and presto! the weird behaviour disappeared.

I understand what you mean when explaining, I'm not used to working in environments where I have to keep track of these things. JavaScript, C#, etc all the way most of the time... Today I learned something new ;)

Thank you for your explanations!

But to programming the impeachment array!

You could try reading the documentation: http://www.microchip.com/webdoc/AVRLibcReferenceManual/group__avr__stdlib_1ga060c998e77fb5fc0d3168b3ce8771d42.html

The caller is responsible for providing sufficient storage in s.

Just say'in.