0

My code is following

#include <iostream>

int main(int argc, char *argv[])
{
  int i = 10;
  char c[3];

  std::cout << i << std::endl;
  sprintf(c, "%d", i);
  std::cout << i << std::endl;

  return 0;
}

Result of it's execution:

10

10

Great, make scene. Let's make char array too small.

#include <iostream>

int main(int argc, char *argv[])
{
  int i = 100;
  char c[3];

  std::cout << i << std::endl;
  sprintf(c, "%d", i);
  std::cout << i << std::endl;

  return 0;
}

Result of it's execution:

100

0

How on Earth i was changed? So sprintf() can change input variables? Why?

  • 2
    undefined behaviour is undefined => dupe of [Undefined, unspecified and implementation-defined behavior](https://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior) – underscore_d Nov 09 '20 at 12:56

2 Answers2

3

"How on Earth i was changed?"

Undefined behaviour.

To elaborate, in the second case, the destination buffer does not have a space to store the terminating null character, thereby the access is made past the valid memory, causing undefined behaviour.

Quoting the sprintf() behaviour (from C11, chapter 7.21.6.6, emphasis mine)

"The sprintf function is equivalent to fprintf, except that the output is written into an array (specified by the argument s) rather than to a stream. A null character is written at the end of the characters written; it is not counted as part of the returned value."

So, while using the function, you need to ensure that the destination buffer is long enough to hold the required value, plus a null terminator.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
1

It's UB.

Looks like i is allocated right after c. When you sprintf "100" it's actually changes 4 bytes, including \0 terminator. So it overwrites i.

Alexander Dmitriev
  • 2,483
  • 1
  • 15
  • 20