In some sample code given by a professor:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char alpha[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
printf( "%s\n", alpha );
printf( "%c\n", alpha[8] );
alpha[8] = 'Z'; /* segmentation fault if alpha is declared statically! */
printf( "%d\n", sizeof( alpha ) );
printf( "%d\n", strlen( alpha ) );
char x[10];
strncpy( x, alpha, 26 );
/* strncpy() will NOT copy or append a '\0' */
printf( "%s\n", x );
return EXIT_SUCCESS;
}
When first compiling and running, the program segfaults due to, from what I see in a few minutes of Googling, a gcc protection mechanism against buffer overflows (triggered by the printf( "%s\n", x ); in which x had been filled with 26 bytes from alpha). This I believe I understand.
However, when disabling the protection mechanism with gcc -fno-stack-protector, the output I see is:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
I
27
26
ABCDEFGHZJKLMNOPQRSTUVWXYZKLMNOPQRSTUVWXYZ
I thought that since strncpy does not null terminate the string, that when X is printed it might actually print the full value of alpha– but in fact, it’s printing all of alpha, and then some more alpha!
Can someone provide some insight here?
With this code:
You are copying 26 bytes of data to a 10-byte array, which means you are overwriting 16 bytes of whatever memory happened to be adjacent to “x”. It this case it looks like what was adjacent to “x” was “alpha”, so you clobbered part of your initial array
When you “printf” x, it keeps printing until it hits a null byte, so it prints out all 26 bytes you copied, plus whatever else is in memory (the surviving contents of “alpha”) until the next null byte.