Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

My char array is confusing me 4

Status
Not open for further replies.

Rmcta

Technical User
Nov 1, 2002
478
US
I wrote the following thinking that "Arthur" would be cut when copied into dest as dest has only 4 spaces.

Why didn't it work that way?


main()
{
int i;

char source[]="Arthur";
char dest[3];

strncpy(dest, source, sizeof(source));

printf("Dest is now:%s\n", dest);

for (i=0; i>6; i++)
printf("%c", dest);


return 0;
}

the output is:
Dest is now:Arthur
Press any key to continue
 
A slight correction: The length provided as the third argument to strncpy must leave room for a null terminator, so this is more appropriate:

Code:
strncpy(dest, source, sizeof(source) - 1);

Sorry for any confusion.

 
I understand I am passing the size of source, but I did that to see if strncpy would cut my source string as there should be not enough space into dest.
Why is test extending?
Shouldn't dest be just 4 spaces?
 
Only four spaces are allocated for dest, but printf() will print until it reaches a null terminator or it attempts to read memory it doesn't have permission to read (causing the program to crash).

The characters that do not fit into dest are still written because your told strncpy() there was enough room. Where do those characters go? They overwrite whatever memory follows dest. Precisely what gets overwritten depends largely on your compiler, but you are likely writing over some padding on the stack (gcc does this) or you are overwriting the first few bytes of source.

Your use of dest causes a "buffer overflow", which is a phrase worth doing a Google search for.

I hope that helps,
Jason Deckard

 
As Jason said C does not stop you from misusing
functions written for general use. Buffer overflows
are really common problems in C.

Write your own version of strncpy just for
educational purposes and make it do the 'right'
thing. You could have it return and copy to
a dynamically alloc'd array if the passed array
is too small, have it return NULL and scold the
user..whatever.

Code:
#include <stdio.h>
#include <stdlib.h>


char *mystrncpy (char *, char *, int);
void myzero (void *, int);




int
main (int argc, char **argv)
{
  char buf[3];
  char *pt;
  if (argc < 2)
    {
      printf ("Need a string arg to the proggy..\n");
      return -1;
    }
  mystrncpy (buf, argv[1], sizeof (buf));
  printf ("%s\n", buf);
  myzero (buf, sizeof (buf));
  if ((pt = mystrncpy (buf, argv[1], strlen (argv[1]))) == NULL)
    {
      printf
	("You are trying to stuff: %d chars into an array with %d chars alloc'd\n",
	 strlen (argv[1]), sizeof (buf));
      return 0;
    }
  printf ("%s\n", buf);
  return 0;
}

char *
mystrncpy (char *dst, char *src, int len)
{
  int p = 0;

  if (dst == NULL || len > sizeof (dst))
    {
      return NULL;
    }
  printf ("Feedback: copying %d chars to array %s from array %s\n", len,
	  "src", "dst");
  while (p < len)
    {
      *dst++ = *src++;
      ++p;
    }
  *dst = '\0';
  return dst;
}

void
myzero (void *ptr, int sz)
{
  int y = 0;
  char *strep = ptr;

  while (y < sz)
    {
      *strep++ = '\0';
      y++;
    }
}
 
Thank you both. I was doing this just to learn and with you help I now understand.
 
Some additions:
Warning#1: mystrncpy() is wrong! sizeof(dst) == sizeof(pointer to char); obviously, it's not a size of a target buffer. Never printf() diagnostics in a common use (i.e. 'library') function (or fprintf(stderr,...). What for "src" and "dst" quoted?
Warning#2: there is an error (misprint?) in the last JasonDeckard's snippet: sizeof(source) instead of sizeof(dest).
About strncpy() library function: be careful. Read its specification (from MSDN):

The strncpy function copies the initial count characters of strSource to strDest and returns strDest. If count is less than or equal to the length of strSource, a null character is not appended automatically to the copied string. If count is greater than the length of strSource, the destination string is padded with null characters up to length count. The behavior of strncpy is undefined if the source and destination strings overlap.

Moral: No safety routines on in principal unsafe C character arrays (called routine can't know true size of its array parameters via pointers).
Make room for zero terminator and don't forget to assign a terminator forcedly...
 
Oops!! Yeah, you'd have to pass the sizeof(dst) from main as an additional arg to mystrncpy() for a valid test. Sorry.
OTOH: I wouldn't preach about not using printf() and then
recommend MSDN as a C programmers resource in the same
post. ;)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top