Question

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?

Was it helpful?

Solution

With this code:

   char x[10];
   strncpy( x, alpha, 26 );

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.

OTHER TIPS

You are just getting lucky. Writing beyond the bounds of an array results in Undefined Behavior.

An Undefined Behavior means that any behavior is possible, it always need not result in a segmentation fault, It simply means the program is not valid and may show any behavior.

Yes, Your program can even seem to work as desired sometimes but it is still iill-formed program as per the standard.

 char x[10];   strncpy( x, alpha, 26 );    
/* strncpy() will NOT copy or append a '\0' */   
printf( "%s\n", x ); 

To strncpy, you are passing, 26 as the value of n, so it copies 26 characters, but when you print using printf, printf will try to search for a '\0' as the terminating character for the string. In this case, somehow the '\0' happens to be present after "KLMNOPQRSTUVWXYZ".

So, in reality, when you do an array out of bounds, you could get any kind of result, a crash, a string that is too long etc.

The question is about the memory layout.
In this program, "alpha" is just behind "x". so when you call

strncpy( x, alpha, 26 );

the data of alpha is being modified.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top