Strcpy on SysV vs. BSD.

Doug Gwyn gwyn at smoke.BRL.MIL
Sun Sep 2 13:39:40 AEST 1990


In article <24351 at adm.BRL.MIL> hsw at sparta.com (Howard Weiss) writes:
>main(){
>  char *TTx = "/dev/";
>  char tty[10]; /* works on both SysV and BSD */
>/*  char *tty;	/* works only on BSD */
>  strcpy(tty,TTx);
>  printf("what's in tty now is %s\n",tty);
>}
>When I tried using the above program on SysV with the 'char *tty;'
>declaration, it compiles fine, but core dumps when run.  The same
>thing occurs if I substitute 'while (*tty++ = *TTx++)' in place of the
>library strcpy.  Yet, the 'char *tty' compiles and runs fine on BSD!
>To get this to work on SysV, I used the 'char tty[10]' declaration.
>Any words of wisdom as to why this is the case would be appreciated!
>I've worked on UNIX systems since V6 (in 1976) and I've never seen
>this before.

Heavens, you've made one of the most common blunders made by novice C
programmers.  In the pointer form of the example, the "tty" variable
is not made to point to valid storage and in fact could contain
arbitrary garbage, since it has never been initialized.  When you
supply this garbage-valued pointer to strcpy(), strcpy() attempts to
use it to point into the target for the copied characters, with
unpredictable results.  Apparently one of the systems you tried this
on happens to not fail very miserably, while the other one does.  The
program is, however, not correct for any system.

The following rewrite contains some instructive comments:

	#include <stdio.h>	/* required for printf() */
	#include <string.h>	/* to properly declare strcpy() */
	int			/* (making this explicit is optional) */
	main( argc, argv )	/* ANSI C permits main() to optionally
				   have no arguments, but old C doesn't */
		int	argc;	/* (making this explicit is optional) */
		char	*argv[];/* or char **argv; which is equivalent
				   for function parameters, but NOT the
				   same thing elsewhere */
	{
		static		/* might as well let the linker init it */
		char	TTx[] =	/* no sense in using a pointer where the
				   array name itself could be used */
			"/dev/";/* initial contents of the TTx[6] array */
		char	tty[10];/* allocates auto storage for 10 chars */
		char	*tp = tty;	/* METHOD 2: points to tty[0] */

		(void)		/* (making this explicit is optional) */
		strcpy( tty, TTx );	/* copy 6 chars into tty[.] */
		(void)strcpy( tp, TTx );/* METHOD 2; same result */
		(void)		/* (making this explicit is optional) */
		printf( "What's in the initial part of tty[] is \"%s\"\n",
			tty	/* or tp */
		      );
		return 0;	/* return "successful" exit status */
	}



More information about the Comp.unix.questions mailing list