Question about sprintf and memory allocation

I've been using sprintf function in my sketches successfully to format and output text to LED display. One thing that puzzles me is that I'm not exactly sure how it allocates memory (and I suspect it causes some weird issues). Specifically if I declared a char array of certain size, but sprintf filled it with a lot more characters it still somehow works.
For example

char myText[4];
sprintf(myText, "Hello. Today is %02d, %d ",day(),year());

It will work despite having only 4 elements in the array. Why?
If I call sprintf again it seems like it erases previous values in myText array. Is it really so, or I'm imagining things? :slight_smile:

Also for some reason it seems I have to declare char array globally. If I create a local version inside function, and then pass it to another function, Arduino usually crashes or reboots.
i.e. something like this:

void makeText () {
char myText[4];
sprintf(myText, "%02d, %02d ",day(),year());
showDate(myText);
}

Yes in the first case sprint will hapilly write over the end of your array and stomp all over whatever was in those next memory locations. Hope it wasn't anything important cause it is corrupted now. It is your responsibility to make sure you declare the array big enough if you don't want to corrupt memory. The compiler won't do that for you.

In the second case it has nothing to do with sprintf. In the second case you've declared a local variable. As soon as that function returns that variable goes out of scope. So you can't use it anywhere else. The same would happen if it was an intended variable and you had just done a simple assignment.

Delta_G:
Yes in the first case sprint will hapilly write over the end of your array and stomp all over whatever was in those next memory locations. Hope it wasn't anything important cause it is corrupted now. It is your responsibility to make sure you declare the array big enough if you don't want to corrupt memory. The compiler won't do that for you.

In the second case it has nothing to do with sprintf. In the second case you've declared a local variable. As soon as that function returns that variable goes out of scope. So you can't use it anywhere else. The same would happen if it was an intended variable and you had just done a simple assignment.

Uh oh, that might explain some unexplained things that's been happening to my program :slight_smile:
Thanks for the info!
What about initializing char array contents? Does sprintf do it every time itself I need to take care of it manually?

bratan:
What about initializing char array contents? Does sprintf do it every time itself I need to take care of it manually?

What do you mean initialize?

Keep in mind that sprintf appends a null terminator, so the array needs to be one larger than you intend touse.

You don't need to initialise the array, apart from declaring it, because sprintf is going to write over what is there anyway.

UKHeliBob:
You don't need to initialise the array, apart from declaring it, because sprintf is going to write over what is there anyway.

Just to clarify.
If for example array is 100 characters long.
First time I call sprintf to fill it with 100 characters.
Then I call it but only fill with 50 characters.
Will it still hold remaining 50 characters from first call at the end?

the char array you declared will still have 100 bytes in it.

void makeText () {
  char myText[4];
  sprintf(myText, "%02d, %02d ",day(),year());
  showDate(myText);
}

Delta_G:
...
In the second case it has nothing to do with sprintf. In the second case you've declared a local variable. As soon as that function returns that variable goes out of scope. So you can't use it anywhere else. The same would happen if it was an intended variable and you had just done a simple assignment.

No, nothing wrong with passing the local variable to another function as in the above code.

The problem is probably putting the 8 characters into the 4 character array. bratan, you need by my count myText[8] to hold what you're trying to put in there ("11, 22 " plus the end of string character)

Cheers,
John

Yes, sprintf does not know how many bytes are available in the buffer so could not really do anything else. You won't be aware of them unless you go looking by reading the char array directly.

By the way, don't try putting 100 characters into a 100 element array using sprintf. As mentioned earlier in the thread space is needed for sprintf to add the null character that signifies then end of the output string.

Thanks everyone! :slight_smile:
Yeah I didn't know about end of string character that's added, this would help!

If you use snprintf() instead, it will avoid trampling off the end of the array.

PeterH:
If you use snprintf() instead, it will avoid trampling off the end of the array.

Wow I didn't know about this function! Thanks a lot!