Michael Schäfer
Michael Schäfer

Reputation: 175

c++ sprintf remove undefined behavior

I know, that something like this

char a[1024] = "Hello";
char b[6] = "World";

sprintf(a, "%s %s", a, b);

causes undefined behavior. I know, I could use other functions like strcat but if I want to use the sprintf function (I know the risk I could write over the array boundaries) could I remove the undefined behavior if I write something like this

sprintf(a + strlen(a), "%s %s", a, b)

or is it still undefined and I have to use a temporary variable?

Upvotes: 1

Views: 989

Answers (2)

eerorika
eerorika

Reputation: 238321

could I remove the undefined behavior if I write something like this

sprintf(a + strlen(a), "%s", b)

or is it still undefined and I have to use a temporary variable?

Yes, you could. No it wouldn't still be UB.


Edit:

could I remove the undefined behavior if I write something like this

sprintf(a + strlen(a), "%s %s", a, b)

or is it still undefined and I have to use a temporary variable?

No, you couldn't. It would still be UB because you still write to the string that you pass as an argument.

Upvotes: 2

Andreas Wenzel
Andreas Wenzel

Reputation: 24736

You are right that the line

sprintf(a, "%s %s", a, b);

will cause undefined behavior, because the source and destination strings overlap.

However, the line

sprintf(a + strlen(a), "%s %s", a, b);

would still cause undefined behavior, because a + strlen(a) is the address of the terminating null character of the string a (which means the source string a and the destination string a + strlen(a) still overlap). If the strings should not overlap, then the line must be changed to the following:

sprintf(a + strlen(a) + 1, "%s %s", a, b);

Since there is no longer any overlap, the line will not cause undefined behavior.

If you want to be able to copy memory from one memory buffer to another memory buffer which overlaps the first memory buffer, then I recommend using the function memmove. In contrast to memcpy, the function memmove permits overlapping memory buffers and behaves as if the content were first written to a temporary buffer before being written to the destination buffer. Therefore, the behavior of that function is not undefined, but well-defined, even if the buffers overlap. Unfortunately, there is no equivalent function strmove for strings.

Upvotes: 2

Related Questions