Right way of defining a buffer when using sprintf - SPI Communication

In my arduino sketch I use sprintf to format a reply. The formatted data will be send using SPI.

I have to set the buffer length, but I don't know how large would be good. Here is a piece of the code:

  uint8_t myValue = 4;

  // Set buffer
  unsigned char data[1000];

  // Format the reply
  sprintf((char *)data, "This is the int value: %d", \
      myValue);

I can also set the buffer to 0 (unsigned char data[0];), The code compiles and the reply is the same as using a large buffer. I can't explain this?

It seems malloc() and free() are pretty rare in the Arduino world...

What is the right way of using a buffer in Arduino?

but I don't know how large would be good.

Why don't you? You can count, can't you?

You count the number of literal characters in the format statement.

  sprintf((char *)data, "This is the int value: %d", myValue);

I count 22.

You know the range of values that can be stored in a variable of type uint8_t (0 to 255). The largest value would take 3 characters.

22 + 3 + 1, for the terminating NULL, is 26.

I can also set the buffer to 0

No, you can't. What you might mean is "I stupidly set the size of the array to 0, and I didn't get burned this time...". Next time is very likely to be a much different story.

It seems malloc() and free() are pretty rare in the Arduino world...

Because they are often misused. There is no reason not to use malloc and free, when used properly AND with awareness of the limited amount of memory that can be allocated and freed AND with awareness that malloc() may not be able to allocate the required amount of space. Then, what do you do?

PaulS:
No, you can't. What you might mean is "I stupidly set the size of the array to 0, and I didn't get burned this time...". Next time is very likely to be a much different story.

Yep, that is what i thought, writing the buffer into memory that is not allocated will get undefined behaviour...

I rather not want to count the buffer size myself for each sprintf...

I will look into snprintf and will update here

fredpeertje:
In my arduino sketch I use sprintf to format a reply. The formatted data will be send using SPI.

What kind of device is connected that really does need formatting?

fredpeertje:
I have to set the buffer length, but I don't know how large would be good.

Your are sending stuf, how can you not know what you send aka how large it is?

fredpeertje:

unsigned char data[1000];

That seems like pissing away memory.

fredpeertje:
I can also set the buffer to 0 (unsigned char data[0];), The code compiles and the reply is the same as using a large buffer. I can't explain this?

That's C/C++, it does NOT check if you go beyond an array, that check is up to you. But if you go beyond an array you have no idea where and what you write to. So it's up to luck if you don't write over stuff you don't want to write over.

fredpeertje:
It seems malloc() and free() are pretty rare in the Arduino world...

Yes, because there is no OS to prevent you from making Swiss cheese from your RAM.

fredpeertje:
What is the right way of using a buffer in Arduino?

Knowing the size of what you want to print. Know why you want to format it in the first place. And know the limitations of a uC compared to a Intel i7.

septillion:
What kind of device is connected that really does need formatting?

Another uC, That reads JSON format

septillion:
Your are sending stuf, how can you not know what you send aka how large it is?

The formatting changes from time to time, so something like this would be handy:
malloc(length + 1);

septillion:
Yes, because there is no OS to prevent you from making Swiss cheese from your RAM.

I prefer Dutch cheese

If there is a uC on both ends, why pick something as "heavy" as JSON?

Have a look at Robin2's "Serial Input Basics". It's written for serial but actually the bus does not matter.

fredpeertje:
I prefer Dutch cheese

Old Dutch cheese please. Although the graskaas was great this year as well. But with malloc() and free() it's easy to turn everything to Maasdammer.