Reputation: 1527
This is the third program in C language. This program is to demonstrate string concept.
From study I know that string at its end has a null character '\0' to terminate the string.
I wrote that code :
main()
{
char name[8];
strcpy(name, "Mahmoud");
printf("The contents of name are %s\n", name);
getchar();
}
In this code I declare array of type char to save string in it. My name "Mahmoud" is 7 chars and I declare name with size 8 which is 7 for "Mahmoud" and 1 for '\0', and it works correctly.
But in the following code:
main()
{
char name[8];
strcpy(name, "MahmoudEmam");
printf("The contents of name are %s\n", name);
getchar();
}
When I display name the output is "MahmoudEmam", although the size of name is 8.
How does it do ?
Upvotes: 2
Views: 3420
Reputation: 355
The question has already been answered, but if I may, I'd like to refine it a bit.
If you notice, strcpy()
does not take buffer length as a parameter. That is because it trusts you, the user, to take care not to overflow the destination buffer.
There is no constrain in C as to what data you can place in what location in memory. That is at the same time a powerfully tool and a dangerous one, if poorly used.
When you call printf()
, it goes through the buffer you provide until it finds the first 0 and prints everything. If you provide a random buffer, it will print gibberish. In the case of the program you wrote, you provided a buffer with the string you copied there. Even though you breached the buffer, the program still managed to find its way and print it because it does not even know the memory is corrupted.
Buffer overflows are one of the hardest bugs you can find. They will often affect parts of the program not related to the module causing the corruption itself and often can take long to have their effect felt. So you should take great care not to cause such a bug!
Upvotes: 1
Reputation: 47583
You are being lucky in this case. What's happening is that you have allocated enough memory on the stack for a 7-letter string (+ one for '\0'
), but you are writing beyond it.
C does not detect reading/writing out of array boundaries for you.
So what's happening is that, you are writing over the rest of the array, destroying whatever else there may be. In a larger program, you will most likely encounter a crash.
This is a good example of why you should learn to use strncpy
, but remember that strncpy
doesn't add the terminating '\0'
if the buffer is full and you should do it yourself. A code like this would do:
strncpy(name, "the text of your string, whatever it is", sizeof(name));
name[sizeof(name) - 1] = '\0';
Upvotes: 2
Reputation: 10695
The fact you see the full name displayed is undefined behavior. Basically, you are copying more than 7 characters and a terminating 0 (total of 8 characters) into storage reserved only for 7 characters and a terminating 0.
It just happens to work, but could as easily cause your program to crash.
This is why C is considered a lower level programming language, or, as the phrase used to go many years ago, a high level assembly programming language.
You the programmer have to check the length of the copy operation's target, using a construct like sizeof(name)
, and make sure what you are copying does not override that space. You must also keep in mind for
string termination, enough space + 1 to account for the terminating '\0'.
Don't forget that using sizeof with a string allocated with malloc will return a value of 4 for a 32-bit pointer, or the pointer length of your hardware. In that case, you'll have to rely on strlen to get the buffer length, or store what size was used to malloc the string.
Finally, when passing a string pointer to a function, writing the function to have a buffer length is very helpful. You cannot get the true buffer length. strlen only returns the string length, not the buffer size actually pointed to by the pointer.
Upvotes: 4
Reputation: 23727
C does not perform any array bounds checking (maybe with C11...). You are writing past the end of your array : it is an undefined behavior (anything can happen).
Upvotes: 6
Reputation: 121427
You are invoking undefined behaviour. You can't rely on that because it works.
Upvotes: 1