Your program invokes undefined behavior.
Undefined behavior is behavior that's out of the specification of the language. By definition, this means that you are not guaranteed to get any kind of well-defined behavior (such as an error). The program is explicitly invalid.
When you use strcpy
, the function simply assumes that the buffer you pass to it is large enough to hold the string you want to copy. If the assumption is wrong, it attempts to write in an area out of the buffer. And if this happens, the program falls into this case of the C specification, in J.2 Undefined behavior:
The behavior is undefined in the following circumstances:
- Addition or subtraction of a pointer into, or just beyond, an array object and an integer type produces a result that does not point into, or just beyond, the same array object
Thus, to use strcpy
correctly, you must manually ensure that the above assumptions about the string's length and the buffer's length hold. To do that, an easy way is to keep the buffer's length saved somewhere, calculate the length of the string you want to copy, and compare them.
For example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
size_t bufferSize = 2 * sizeof(char);
char *name = malloc(bufferSize);
if(name == NULL) {
fprintf(stderr, "Error: Unable to allocate enough memory!\n");
return EXIT_FAILURE;
}
size_t length = strlen("Bob Smith");
if(length + 1 > bufferSize) {
fprintf(stderr, "Error: The target buffer is too small!\n");
return EXIT_FAILURE;
}
strcpy(name, "Bob Smith");
printf("Name: %s\n", name);
free(name);
return EXIT_SUCCESS;
}
As an unrelated side note, you'll notice that I didn't cast the result of malloc
, because a void*
is implicitly convertible to char*
.
As a final note:
This aspect of C may sound impractical when you're trying to ensure the correctness of your code (either because you're learning the language or because you intend to release the software).
This is why there are some tools that offer to give you an error whenever your program does something invalid. Valgrind is one such tool (as was mentioned by Jonathan Leffler in the comments).